tlv320aic23.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670
  1. /*
  2. * ALSA SoC TLV320AIC23 codec driver
  3. *
  4. * Author: Arun KS, <arunks@mistralsolutions.com>
  5. * Copyright: (C) 2008 Mistral Solutions Pvt Ltd.,
  6. *
  7. * Based on sound/soc/codecs/wm8731.c by Richard Purdie
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License version 2 as
  11. * published by the Free Software Foundation.
  12. *
  13. * Notes:
  14. * The AIC23 is a driver for a low power stereo audio
  15. * codec tlv320aic23
  16. *
  17. * The machine layer should disable unsupported inputs/outputs by
  18. * snd_soc_dapm_disable_pin(codec, "LHPOUT"), etc.
  19. */
  20. #include <linux/module.h>
  21. #include <linux/moduleparam.h>
  22. #include <linux/init.h>
  23. #include <linux/delay.h>
  24. #include <linux/pm.h>
  25. #include <linux/i2c.h>
  26. #include <linux/platform_device.h>
  27. #include <sound/core.h>
  28. #include <sound/pcm.h>
  29. #include <sound/pcm_params.h>
  30. #include <sound/soc.h>
  31. #include <sound/soc-dapm.h>
  32. #include <sound/tlv.h>
  33. #include <sound/initval.h>
  34. #include "tlv320aic23.h"
  35. #define AUDIO_NAME "tlv320aic23"
  36. #define AIC23_VERSION "0.1"
  37. struct tlv320aic23_srate_reg_info {
  38. u32 sample_rate;
  39. u8 control; /* SR3, SR2, SR1, SR0 and BOSR */
  40. u8 divider; /* if 0 CLKIN = MCLK, if 1 CLKIN = MCLK/2 */
  41. };
  42. /*
  43. * AIC23 register cache
  44. */
  45. static const u16 tlv320aic23_reg[] = {
  46. 0x0097, 0x0097, 0x00F9, 0x00F9, /* 0 */
  47. 0x001A, 0x0004, 0x0007, 0x0001, /* 4 */
  48. 0x0020, 0x0000, 0x0000, 0x0000, /* 8 */
  49. 0x0000, 0x0000, 0x0000, 0x0000, /* 12 */
  50. };
  51. /*
  52. * read tlv320aic23 register cache
  53. */
  54. static inline unsigned int tlv320aic23_read_reg_cache(struct snd_soc_codec
  55. *codec, unsigned int reg)
  56. {
  57. u16 *cache = codec->reg_cache;
  58. if (reg >= ARRAY_SIZE(tlv320aic23_reg))
  59. return -1;
  60. return cache[reg];
  61. }
  62. /*
  63. * write tlv320aic23 register cache
  64. */
  65. static inline void tlv320aic23_write_reg_cache(struct snd_soc_codec *codec,
  66. u8 reg, u16 value)
  67. {
  68. u16 *cache = codec->reg_cache;
  69. if (reg >= ARRAY_SIZE(tlv320aic23_reg))
  70. return;
  71. cache[reg] = value;
  72. }
  73. /*
  74. * write to the tlv320aic23 register space
  75. */
  76. static int tlv320aic23_write(struct snd_soc_codec *codec, unsigned int reg,
  77. unsigned int value)
  78. {
  79. u8 data;
  80. /* TLV320AIC23 has 7 bit address and 9 bits of data
  81. * so we need to switch one data bit into reg and rest
  82. * of data into val
  83. */
  84. if ((reg < 0 || reg > 9) && (reg != 15)) {
  85. printk(KERN_WARNING "%s Invalid register R%d\n", __func__, reg);
  86. return -1;
  87. }
  88. data = (reg << 1) | (value >> 8 & 0x01);
  89. tlv320aic23_write_reg_cache(codec, reg, value);
  90. if (codec->hw_write(codec->control_data, data,
  91. (value & 0xff)) == 0)
  92. return 0;
  93. printk(KERN_ERR "%s cannot write %03x to register R%d\n", __func__,
  94. value, reg);
  95. return -EIO;
  96. }
  97. static const char *rec_src_text[] = { "Line", "Mic" };
  98. static const char *deemph_text[] = {"None", "32Khz", "44.1Khz", "48Khz"};
  99. static const char *sidetone_text[] = {"-6db", "-9db", "-12db", "-18db", "0db"};
  100. static const struct soc_enum rec_src_enum =
  101. SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 2, 2, rec_src_text);
  102. static const struct snd_kcontrol_new tlv320aic23_rec_src_mux_controls =
  103. SOC_DAPM_ENUM("Input Select", rec_src_enum);
  104. static const struct soc_enum tlv320aic23_rec_src =
  105. SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 2, 2, rec_src_text);
  106. static const struct soc_enum tlv320aic23_deemph =
  107. SOC_ENUM_SINGLE(TLV320AIC23_DIGT, 1, 4, deemph_text);
  108. static const struct soc_enum tlv320aic23_sidetone =
  109. SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 6, 5, sidetone_text);
  110. static const DECLARE_TLV_DB_SCALE(out_gain_tlv, -12100, 100, 0);
  111. static const DECLARE_TLV_DB_SCALE(input_gain_tlv, -1725, 75, 0);
  112. static const struct snd_kcontrol_new tlv320aic23_snd_controls[] = {
  113. SOC_DOUBLE_R_TLV("Digital Playback Volume", TLV320AIC23_LCHNVOL,
  114. TLV320AIC23_RCHNVOL, 0, 127, 0, out_gain_tlv),
  115. SOC_SINGLE("Digital Playback Switch", TLV320AIC23_DIGT, 3, 1, 1),
  116. SOC_DOUBLE_R("Line Input Switch", TLV320AIC23_LINVOL,
  117. TLV320AIC23_RINVOL, 7, 1, 0),
  118. SOC_DOUBLE_R_TLV("Line Input Volume", TLV320AIC23_LINVOL,
  119. TLV320AIC23_RINVOL, 0, 31, 0, input_gain_tlv),
  120. SOC_SINGLE("Mic Input Switch", TLV320AIC23_ANLG, 1, 1, 1),
  121. SOC_SINGLE("Mic Booster Switch", TLV320AIC23_ANLG, 0, 1, 0),
  122. SOC_ENUM("Sidetone Gain", tlv320aic23_sidetone),
  123. SOC_ENUM("Playback De-emphasis", tlv320aic23_deemph),
  124. };
  125. /* add non dapm controls */
  126. static int tlv320aic23_add_controls(struct snd_soc_codec *codec)
  127. {
  128. int err, i;
  129. for (i = 0; i < ARRAY_SIZE(tlv320aic23_snd_controls); i++) {
  130. err = snd_ctl_add(codec->card,
  131. snd_soc_cnew(&tlv320aic23_snd_controls[i],
  132. codec, NULL));
  133. if (err < 0)
  134. return err;
  135. }
  136. return 0;
  137. }
  138. /* PGA Mixer controls for Line and Mic switch */
  139. static const struct snd_kcontrol_new tlv320aic23_output_mixer_controls[] = {
  140. SOC_DAPM_SINGLE("Line Bypass Switch", TLV320AIC23_ANLG, 3, 1, 0),
  141. SOC_DAPM_SINGLE("Mic Sidetone Switch", TLV320AIC23_ANLG, 5, 1, 0),
  142. SOC_DAPM_SINGLE("Playback Switch", TLV320AIC23_ANLG, 4, 1, 0),
  143. };
  144. static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = {
  145. SND_SOC_DAPM_DAC("DAC", "Playback", TLV320AIC23_PWR, 3, 1),
  146. SND_SOC_DAPM_ADC("ADC", "Capture", TLV320AIC23_PWR, 2, 1),
  147. SND_SOC_DAPM_MUX("Capture Source", SND_SOC_NOPM, 0, 0,
  148. &tlv320aic23_rec_src_mux_controls),
  149. SND_SOC_DAPM_MIXER("Output Mixer", TLV320AIC23_PWR, 4, 1,
  150. &tlv320aic23_output_mixer_controls[0],
  151. ARRAY_SIZE(tlv320aic23_output_mixer_controls)),
  152. SND_SOC_DAPM_PGA("Line Input", TLV320AIC23_PWR, 0, 1, NULL, 0),
  153. SND_SOC_DAPM_PGA("Mic Input", TLV320AIC23_PWR, 1, 1, NULL, 0),
  154. SND_SOC_DAPM_OUTPUT("LHPOUT"),
  155. SND_SOC_DAPM_OUTPUT("RHPOUT"),
  156. SND_SOC_DAPM_OUTPUT("LOUT"),
  157. SND_SOC_DAPM_OUTPUT("ROUT"),
  158. SND_SOC_DAPM_INPUT("LLINEIN"),
  159. SND_SOC_DAPM_INPUT("RLINEIN"),
  160. SND_SOC_DAPM_INPUT("MICIN"),
  161. };
  162. static const struct snd_soc_dapm_route intercon[] = {
  163. /* Output Mixer */
  164. {"Output Mixer", "Line Bypass Switch", "Line Input"},
  165. {"Output Mixer", "Playback Switch", "DAC"},
  166. {"Output Mixer", "Mic Sidetone Switch", "Mic Input"},
  167. /* Outputs */
  168. {"RHPOUT", NULL, "Output Mixer"},
  169. {"LHPOUT", NULL, "Output Mixer"},
  170. {"LOUT", NULL, "Output Mixer"},
  171. {"ROUT", NULL, "Output Mixer"},
  172. /* Inputs */
  173. {"Line Input", "NULL", "LLINEIN"},
  174. {"Line Input", "NULL", "RLINEIN"},
  175. {"Mic Input", "NULL", "MICIN"},
  176. /* input mux */
  177. {"Capture Source", "Line", "Line Input"},
  178. {"Capture Source", "Mic", "Mic Input"},
  179. {"ADC", NULL, "Capture Source"},
  180. };
  181. /* tlv320aic23 related */
  182. static const struct tlv320aic23_srate_reg_info srate_reg_info[] = {
  183. {4000, 0x06, 1}, /* 4000 */
  184. {8000, 0x06, 0}, /* 8000 */
  185. {16000, 0x0C, 1}, /* 16000 */
  186. {22050, 0x11, 1}, /* 22050 */
  187. {24000, 0x00, 1}, /* 24000 */
  188. {32000, 0x0C, 0}, /* 32000 */
  189. {44100, 0x11, 0}, /* 44100 */
  190. {48000, 0x00, 0}, /* 48000 */
  191. {88200, 0x1F, 0}, /* 88200 */
  192. {96000, 0x0E, 0}, /* 96000 */
  193. };
  194. static int tlv320aic23_add_widgets(struct snd_soc_codec *codec)
  195. {
  196. snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
  197. ARRAY_SIZE(tlv320aic23_dapm_widgets));
  198. /* set up audio path interconnects */
  199. snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
  200. snd_soc_dapm_new_widgets(codec);
  201. return 0;
  202. }
  203. static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
  204. struct snd_pcm_hw_params *params)
  205. {
  206. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  207. struct snd_soc_device *socdev = rtd->socdev;
  208. struct snd_soc_codec *codec = socdev->codec;
  209. u16 iface_reg, data;
  210. u8 count = 0;
  211. iface_reg =
  212. tlv320aic23_read_reg_cache(codec,
  213. TLV320AIC23_DIGT_FMT) & ~(0x03 << 2);
  214. /* Search for the right sample rate */
  215. /* Verify what happens if the rate is not supported
  216. * now it goes to 96Khz */
  217. while ((srate_reg_info[count].sample_rate != params_rate(params)) &&
  218. (count < ARRAY_SIZE(srate_reg_info))) {
  219. count++;
  220. }
  221. data = (srate_reg_info[count].divider << TLV320AIC23_CLKIN_SHIFT) |
  222. (srate_reg_info[count]. control << TLV320AIC23_BOSR_SHIFT) |
  223. TLV320AIC23_USB_CLK_ON;
  224. tlv320aic23_write(codec, TLV320AIC23_SRATE, data);
  225. switch (params_format(params)) {
  226. case SNDRV_PCM_FORMAT_S16_LE:
  227. break;
  228. case SNDRV_PCM_FORMAT_S20_3LE:
  229. iface_reg |= (0x01 << 2);
  230. break;
  231. case SNDRV_PCM_FORMAT_S24_LE:
  232. iface_reg |= (0x02 << 2);
  233. break;
  234. case SNDRV_PCM_FORMAT_S32_LE:
  235. iface_reg |= (0x03 << 2);
  236. break;
  237. }
  238. tlv320aic23_write(codec, TLV320AIC23_DIGT_FMT, iface_reg);
  239. return 0;
  240. }
  241. static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream)
  242. {
  243. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  244. struct snd_soc_device *socdev = rtd->socdev;
  245. struct snd_soc_codec *codec = socdev->codec;
  246. /* set active */
  247. tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0001);
  248. return 0;
  249. }
  250. static void tlv320aic23_shutdown(struct snd_pcm_substream *substream)
  251. {
  252. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  253. struct snd_soc_device *socdev = rtd->socdev;
  254. struct snd_soc_codec *codec = socdev->codec;
  255. /* deactivate */
  256. if (!codec->active) {
  257. udelay(50);
  258. tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0);
  259. }
  260. }
  261. static int tlv320aic23_mute(struct snd_soc_dai *dai, int mute)
  262. {
  263. struct snd_soc_codec *codec = dai->codec;
  264. u16 reg;
  265. reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_DIGT);
  266. if (mute)
  267. reg |= TLV320AIC23_DACM_MUTE;
  268. else
  269. reg &= ~TLV320AIC23_DACM_MUTE;
  270. tlv320aic23_write(codec, TLV320AIC23_DIGT, reg);
  271. return 0;
  272. }
  273. static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai,
  274. unsigned int fmt)
  275. {
  276. struct snd_soc_codec *codec = codec_dai->codec;
  277. u16 iface_reg;
  278. iface_reg =
  279. tlv320aic23_read_reg_cache(codec, TLV320AIC23_DIGT_FMT) & (~0x03);
  280. /* set master/slave audio interface */
  281. switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
  282. case SND_SOC_DAIFMT_CBM_CFM:
  283. iface_reg |= TLV320AIC23_MS_MASTER;
  284. break;
  285. case SND_SOC_DAIFMT_CBS_CFS:
  286. break;
  287. default:
  288. return -EINVAL;
  289. }
  290. /* interface format */
  291. switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
  292. case SND_SOC_DAIFMT_I2S:
  293. iface_reg |= TLV320AIC23_FOR_I2S;
  294. break;
  295. case SND_SOC_DAIFMT_DSP_A:
  296. iface_reg |= TLV320AIC23_FOR_DSP;
  297. break;
  298. case SND_SOC_DAIFMT_RIGHT_J:
  299. break;
  300. case SND_SOC_DAIFMT_LEFT_J:
  301. iface_reg |= TLV320AIC23_FOR_LJUST;
  302. break;
  303. default:
  304. return -EINVAL;
  305. }
  306. tlv320aic23_write(codec, TLV320AIC23_DIGT_FMT, iface_reg);
  307. return 0;
  308. }
  309. static int tlv320aic23_set_dai_sysclk(struct snd_soc_dai *codec_dai,
  310. int clk_id, unsigned int freq, int dir)
  311. {
  312. struct snd_soc_codec *codec = codec_dai->codec;
  313. switch (freq) {
  314. case 12000000:
  315. return 0;
  316. }
  317. return -EINVAL;
  318. }
  319. static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec,
  320. enum snd_soc_bias_level level)
  321. {
  322. u16 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_PWR) & 0xff7f;
  323. switch (level) {
  324. case SND_SOC_BIAS_ON:
  325. /* vref/mid, osc on, dac unmute */
  326. tlv320aic23_write(codec, TLV320AIC23_PWR, reg);
  327. break;
  328. case SND_SOC_BIAS_PREPARE:
  329. break;
  330. case SND_SOC_BIAS_STANDBY:
  331. /* everything off except vref/vmid, */
  332. tlv320aic23_write(codec, TLV320AIC23_PWR, reg | 0x0040);
  333. break;
  334. case SND_SOC_BIAS_OFF:
  335. /* everything off, dac mute, inactive */
  336. tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0);
  337. tlv320aic23_write(codec, TLV320AIC23_PWR, 0xffff);
  338. break;
  339. }
  340. codec->bias_level = level;
  341. return 0;
  342. }
  343. #define AIC23_RATES SNDRV_PCM_RATE_8000_96000
  344. #define AIC23_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
  345. SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
  346. struct snd_soc_dai tlv320aic23_dai = {
  347. .name = "tlv320aic23",
  348. .playback = {
  349. .stream_name = "Playback",
  350. .channels_min = 2,
  351. .channels_max = 2,
  352. .rates = AIC23_RATES,
  353. .formats = AIC23_FORMATS,},
  354. .capture = {
  355. .stream_name = "Capture",
  356. .channels_min = 2,
  357. .channels_max = 2,
  358. .rates = AIC23_RATES,
  359. .formats = AIC23_FORMATS,},
  360. .ops = {
  361. .prepare = tlv320aic23_pcm_prepare,
  362. .hw_params = tlv320aic23_hw_params,
  363. .shutdown = tlv320aic23_shutdown,
  364. },
  365. .dai_ops = {
  366. .digital_mute = tlv320aic23_mute,
  367. .set_fmt = tlv320aic23_set_dai_fmt,
  368. .set_sysclk = tlv320aic23_set_dai_sysclk,
  369. }
  370. };
  371. EXPORT_SYMBOL_GPL(tlv320aic23_dai);
  372. static int tlv320aic23_suspend(struct platform_device *pdev,
  373. pm_message_t state)
  374. {
  375. struct snd_soc_device *socdev = platform_get_drvdata(pdev);
  376. struct snd_soc_codec *codec = socdev->codec;
  377. tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0);
  378. tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF);
  379. return 0;
  380. }
  381. static int tlv320aic23_resume(struct platform_device *pdev)
  382. {
  383. struct snd_soc_device *socdev = platform_get_drvdata(pdev);
  384. struct snd_soc_codec *codec = socdev->codec;
  385. int i;
  386. u16 reg;
  387. /* Sync reg_cache with the hardware */
  388. for (reg = 0; reg < ARRAY_SIZE(tlv320aic23_reg); i++) {
  389. u16 val = tlv320aic23_read_reg_cache(codec, reg);
  390. tlv320aic23_write(codec, reg, val);
  391. }
  392. tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
  393. tlv320aic23_set_bias_level(codec, codec->suspend_bias_level);
  394. return 0;
  395. }
  396. /*
  397. * initialise the AIC23 driver
  398. * register the mixer and dsp interfaces with the kernel
  399. */
  400. static int tlv320aic23_init(struct snd_soc_device *socdev)
  401. {
  402. struct snd_soc_codec *codec = socdev->codec;
  403. int ret = 0;
  404. u16 reg;
  405. codec->name = "tlv320aic23";
  406. codec->owner = THIS_MODULE;
  407. codec->read = tlv320aic23_read_reg_cache;
  408. codec->write = tlv320aic23_write;
  409. codec->set_bias_level = tlv320aic23_set_bias_level;
  410. codec->dai = &tlv320aic23_dai;
  411. codec->num_dai = 1;
  412. codec->reg_cache_size = ARRAY_SIZE(tlv320aic23_reg);
  413. codec->reg_cache =
  414. kmemdup(tlv320aic23_reg, sizeof(tlv320aic23_reg), GFP_KERNEL);
  415. if (codec->reg_cache == NULL)
  416. return -ENOMEM;
  417. /* Reset codec */
  418. tlv320aic23_write(codec, TLV320AIC23_RESET, 0);
  419. /* register pcms */
  420. ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
  421. if (ret < 0) {
  422. printk(KERN_ERR "tlv320aic23: failed to create pcms\n");
  423. goto pcm_err;
  424. }
  425. /* power on device */
  426. tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
  427. tlv320aic23_write(codec, TLV320AIC23_DIGT, TLV320AIC23_DEEMP_44K);
  428. /* Unmute input */
  429. reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_LINVOL);
  430. tlv320aic23_write(codec, TLV320AIC23_LINVOL,
  431. (reg & (~TLV320AIC23_LIM_MUTED)) |
  432. (TLV320AIC23_LRS_ENABLED));
  433. reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_RINVOL);
  434. tlv320aic23_write(codec, TLV320AIC23_RINVOL,
  435. (reg & (~TLV320AIC23_LIM_MUTED)) |
  436. TLV320AIC23_LRS_ENABLED);
  437. reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_ANLG);
  438. tlv320aic23_write(codec, TLV320AIC23_ANLG,
  439. (reg) & (~TLV320AIC23_BYPASS_ON) &
  440. (~TLV320AIC23_MICM_MUTED));
  441. /* Default output volume */
  442. tlv320aic23_write(codec, TLV320AIC23_LCHNVOL,
  443. TLV320AIC23_DEFAULT_OUT_VOL &
  444. TLV320AIC23_OUT_VOL_MASK);
  445. tlv320aic23_write(codec, TLV320AIC23_RCHNVOL,
  446. TLV320AIC23_DEFAULT_OUT_VOL &
  447. TLV320AIC23_OUT_VOL_MASK);
  448. tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x1);
  449. tlv320aic23_add_controls(codec);
  450. tlv320aic23_add_widgets(codec);
  451. ret = snd_soc_register_card(socdev);
  452. if (ret < 0) {
  453. printk(KERN_ERR "tlv320aic23: failed to register card\n");
  454. goto card_err;
  455. }
  456. return ret;
  457. card_err:
  458. snd_soc_free_pcms(socdev);
  459. snd_soc_dapm_free(socdev);
  460. pcm_err:
  461. kfree(codec->reg_cache);
  462. return ret;
  463. }
  464. static struct snd_soc_device *tlv320aic23_socdev;
  465. #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
  466. /*
  467. * If the i2c layer weren't so broken, we could pass this kind of data
  468. * around
  469. */
  470. static int tlv320aic23_codec_probe(struct i2c_client *i2c,
  471. const struct i2c_device_id *i2c_id)
  472. {
  473. struct snd_soc_device *socdev = tlv320aic23_socdev;
  474. struct snd_soc_codec *codec = socdev->codec;
  475. int ret;
  476. if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
  477. return -EINVAL;
  478. i2c_set_clientdata(i2c, codec);
  479. codec->control_data = i2c;
  480. ret = tlv320aic23_init(socdev);
  481. if (ret < 0) {
  482. printk(KERN_ERR "tlv320aic23: failed to initialise AIC23\n");
  483. goto err;
  484. }
  485. return ret;
  486. err:
  487. kfree(codec);
  488. kfree(i2c);
  489. return ret;
  490. }
  491. static int __exit tlv320aic23_i2c_remove(struct i2c_client *i2c)
  492. {
  493. put_device(&i2c->dev);
  494. return 0;
  495. }
  496. static const struct i2c_device_id tlv320aic23_id[] = {
  497. {"tlv320aic23", 0},
  498. {}
  499. };
  500. MODULE_DEVICE_TABLE(i2c, tlv320aic23_id);
  501. static struct i2c_driver tlv320aic23_i2c_driver = {
  502. .driver = {
  503. .name = "tlv320aic23",
  504. },
  505. .probe = tlv320aic23_codec_probe,
  506. .remove = __exit_p(tlv320aic23_i2c_remove),
  507. .id_table = tlv320aic23_id,
  508. };
  509. #endif
  510. static int tlv320aic23_probe(struct platform_device *pdev)
  511. {
  512. struct snd_soc_device *socdev = platform_get_drvdata(pdev);
  513. struct snd_soc_codec *codec;
  514. int ret = 0;
  515. printk(KERN_INFO "AIC23 Audio Codec %s\n", AIC23_VERSION);
  516. codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
  517. if (codec == NULL)
  518. return -ENOMEM;
  519. socdev->codec = codec;
  520. mutex_init(&codec->mutex);
  521. INIT_LIST_HEAD(&codec->dapm_widgets);
  522. INIT_LIST_HEAD(&codec->dapm_paths);
  523. tlv320aic23_socdev = socdev;
  524. #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
  525. codec->hw_write = (hw_write_t) i2c_smbus_write_byte_data;
  526. codec->hw_read = NULL;
  527. ret = i2c_add_driver(&tlv320aic23_i2c_driver);
  528. if (ret != 0)
  529. printk(KERN_ERR "can't add i2c driver");
  530. #endif
  531. return ret;
  532. }
  533. static int tlv320aic23_remove(struct platform_device *pdev)
  534. {
  535. struct snd_soc_device *socdev = platform_get_drvdata(pdev);
  536. struct snd_soc_codec *codec = socdev->codec;
  537. if (codec->control_data)
  538. tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF);
  539. snd_soc_free_pcms(socdev);
  540. snd_soc_dapm_free(socdev);
  541. #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
  542. i2c_del_driver(&tlv320aic23_i2c_driver);
  543. #endif
  544. kfree(codec->reg_cache);
  545. kfree(codec);
  546. return 0;
  547. }
  548. struct snd_soc_codec_device soc_codec_dev_tlv320aic23 = {
  549. .probe = tlv320aic23_probe,
  550. .remove = tlv320aic23_remove,
  551. .suspend = tlv320aic23_suspend,
  552. .resume = tlv320aic23_resume,
  553. };
  554. EXPORT_SYMBOL_GPL(soc_codec_dev_tlv320aic23);
  555. MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver");
  556. MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>");
  557. MODULE_LICENSE("GPL");