twl4030.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317
  1. /*
  2. * ALSA SoC TWL4030 codec driver
  3. *
  4. * Author: Steve Sakoman, <steve@sakoman.com>
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * version 2 as published by the Free Software Foundation.
  9. *
  10. * This program is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  18. * 02110-1301 USA
  19. *
  20. */
  21. #include <linux/module.h>
  22. #include <linux/moduleparam.h>
  23. #include <linux/init.h>
  24. #include <linux/delay.h>
  25. #include <linux/pm.h>
  26. #include <linux/i2c.h>
  27. #include <linux/platform_device.h>
  28. #include <linux/i2c/twl4030.h>
  29. #include <sound/core.h>
  30. #include <sound/pcm.h>
  31. #include <sound/pcm_params.h>
  32. #include <sound/soc.h>
  33. #include <sound/soc-dapm.h>
  34. #include <sound/initval.h>
  35. #include <sound/tlv.h>
  36. #include "twl4030.h"
  37. /*
  38. * twl4030 register cache & default register settings
  39. */
  40. static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
  41. 0x00, /* this register not used */
  42. 0x93, /* REG_CODEC_MODE (0x1) */
  43. 0xc3, /* REG_OPTION (0x2) */
  44. 0x00, /* REG_UNKNOWN (0x3) */
  45. 0x00, /* REG_MICBIAS_CTL (0x4) */
  46. 0x20, /* REG_ANAMICL (0x5) */
  47. 0x00, /* REG_ANAMICR (0x6) */
  48. 0x00, /* REG_AVADC_CTL (0x7) */
  49. 0x00, /* REG_ADCMICSEL (0x8) */
  50. 0x00, /* REG_DIGMIXING (0x9) */
  51. 0x0c, /* REG_ATXL1PGA (0xA) */
  52. 0x0c, /* REG_ATXR1PGA (0xB) */
  53. 0x00, /* REG_AVTXL2PGA (0xC) */
  54. 0x00, /* REG_AVTXR2PGA (0xD) */
  55. 0x01, /* REG_AUDIO_IF (0xE) */
  56. 0x00, /* REG_VOICE_IF (0xF) */
  57. 0x00, /* REG_ARXR1PGA (0x10) */
  58. 0x00, /* REG_ARXL1PGA (0x11) */
  59. 0x6c, /* REG_ARXR2PGA (0x12) */
  60. 0x6c, /* REG_ARXL2PGA (0x13) */
  61. 0x00, /* REG_VRXPGA (0x14) */
  62. 0x00, /* REG_VSTPGA (0x15) */
  63. 0x00, /* REG_VRX2ARXPGA (0x16) */
  64. 0x0c, /* REG_AVDAC_CTL (0x17) */
  65. 0x00, /* REG_ARX2VTXPGA (0x18) */
  66. 0x00, /* REG_ARXL1_APGA_CTL (0x19) */
  67. 0x00, /* REG_ARXR1_APGA_CTL (0x1A) */
  68. 0x4b, /* REG_ARXL2_APGA_CTL (0x1B) */
  69. 0x4b, /* REG_ARXR2_APGA_CTL (0x1C) */
  70. 0x00, /* REG_ATX2ARXPGA (0x1D) */
  71. 0x00, /* REG_BT_IF (0x1E) */
  72. 0x00, /* REG_BTPGA (0x1F) */
  73. 0x00, /* REG_BTSTPGA (0x20) */
  74. 0x00, /* REG_EAR_CTL (0x21) */
  75. 0x24, /* REG_HS_SEL (0x22) */
  76. 0x0a, /* REG_HS_GAIN_SET (0x23) */
  77. 0x00, /* REG_HS_POPN_SET (0x24) */
  78. 0x00, /* REG_PREDL_CTL (0x25) */
  79. 0x00, /* REG_PREDR_CTL (0x26) */
  80. 0x00, /* REG_PRECKL_CTL (0x27) */
  81. 0x00, /* REG_PRECKR_CTL (0x28) */
  82. 0x00, /* REG_HFL_CTL (0x29) */
  83. 0x00, /* REG_HFR_CTL (0x2A) */
  84. 0x00, /* REG_ALC_CTL (0x2B) */
  85. 0x00, /* REG_ALC_SET1 (0x2C) */
  86. 0x00, /* REG_ALC_SET2 (0x2D) */
  87. 0x00, /* REG_BOOST_CTL (0x2E) */
  88. 0x00, /* REG_SOFTVOL_CTL (0x2F) */
  89. 0x00, /* REG_DTMF_FREQSEL (0x30) */
  90. 0x00, /* REG_DTMF_TONEXT1H (0x31) */
  91. 0x00, /* REG_DTMF_TONEXT1L (0x32) */
  92. 0x00, /* REG_DTMF_TONEXT2H (0x33) */
  93. 0x00, /* REG_DTMF_TONEXT2L (0x34) */
  94. 0x00, /* REG_DTMF_TONOFF (0x35) */
  95. 0x00, /* REG_DTMF_WANONOFF (0x36) */
  96. 0x00, /* REG_I2S_RX_SCRAMBLE_H (0x37) */
  97. 0x00, /* REG_I2S_RX_SCRAMBLE_M (0x38) */
  98. 0x00, /* REG_I2S_RX_SCRAMBLE_L (0x39) */
  99. 0x16, /* REG_APLL_CTL (0x3A) */
  100. 0x00, /* REG_DTMF_CTL (0x3B) */
  101. 0x00, /* REG_DTMF_PGA_CTL2 (0x3C) */
  102. 0x00, /* REG_DTMF_PGA_CTL1 (0x3D) */
  103. 0x00, /* REG_MISC_SET_1 (0x3E) */
  104. 0x00, /* REG_PCMBTMUX (0x3F) */
  105. 0x00, /* not used (0x40) */
  106. 0x00, /* not used (0x41) */
  107. 0x00, /* not used (0x42) */
  108. 0x00, /* REG_RX_PATH_SEL (0x43) */
  109. 0x00, /* REG_VDL_APGA_CTL (0x44) */
  110. 0x00, /* REG_VIBRA_CTL (0x45) */
  111. 0x00, /* REG_VIBRA_SET (0x46) */
  112. 0x00, /* REG_VIBRA_PWM_SET (0x47) */
  113. 0x00, /* REG_ANAMIC_GAIN (0x48) */
  114. 0x00, /* REG_MISC_SET_2 (0x49) */
  115. };
  116. /*
  117. * read twl4030 register cache
  118. */
  119. static inline unsigned int twl4030_read_reg_cache(struct snd_soc_codec *codec,
  120. unsigned int reg)
  121. {
  122. u8 *cache = codec->reg_cache;
  123. return cache[reg];
  124. }
  125. /*
  126. * write twl4030 register cache
  127. */
  128. static inline void twl4030_write_reg_cache(struct snd_soc_codec *codec,
  129. u8 reg, u8 value)
  130. {
  131. u8 *cache = codec->reg_cache;
  132. if (reg >= TWL4030_CACHEREGNUM)
  133. return;
  134. cache[reg] = value;
  135. }
  136. /*
  137. * write to the twl4030 register space
  138. */
  139. static int twl4030_write(struct snd_soc_codec *codec,
  140. unsigned int reg, unsigned int value)
  141. {
  142. twl4030_write_reg_cache(codec, reg, value);
  143. return twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, reg);
  144. }
  145. static void twl4030_clear_codecpdz(struct snd_soc_codec *codec)
  146. {
  147. u8 mode;
  148. mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE);
  149. twl4030_write(codec, TWL4030_REG_CODEC_MODE,
  150. mode & ~TWL4030_CODECPDZ);
  151. /* REVISIT: this delay is present in TI sample drivers */
  152. /* but there seems to be no TRM requirement for it */
  153. udelay(10);
  154. }
  155. static void twl4030_set_codecpdz(struct snd_soc_codec *codec)
  156. {
  157. u8 mode;
  158. mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE);
  159. twl4030_write(codec, TWL4030_REG_CODEC_MODE,
  160. mode | TWL4030_CODECPDZ);
  161. /* REVISIT: this delay is present in TI sample drivers */
  162. /* but there seems to be no TRM requirement for it */
  163. udelay(10);
  164. }
  165. static void twl4030_init_chip(struct snd_soc_codec *codec)
  166. {
  167. int i;
  168. /* clear CODECPDZ prior to setting register defaults */
  169. twl4030_clear_codecpdz(codec);
  170. /* set all audio section registers to reasonable defaults */
  171. for (i = TWL4030_REG_OPTION; i <= TWL4030_REG_MISC_SET_2; i++)
  172. twl4030_write(codec, i, twl4030_reg[i]);
  173. }
  174. /* Earpiece */
  175. static const char *twl4030_earpiece_texts[] =
  176. {"Off", "DACL1", "DACL2", "Invalid", "DACR1"};
  177. static const struct soc_enum twl4030_earpiece_enum =
  178. SOC_ENUM_SINGLE(TWL4030_REG_EAR_CTL, 1,
  179. ARRAY_SIZE(twl4030_earpiece_texts),
  180. twl4030_earpiece_texts);
  181. static const struct snd_kcontrol_new twl4030_dapm_earpiece_control =
  182. SOC_DAPM_ENUM("Route", twl4030_earpiece_enum);
  183. /* PreDrive Left */
  184. static const char *twl4030_predrivel_texts[] =
  185. {"Off", "DACL1", "DACL2", "Invalid", "DACR2"};
  186. static const struct soc_enum twl4030_predrivel_enum =
  187. SOC_ENUM_SINGLE(TWL4030_REG_PREDL_CTL, 1,
  188. ARRAY_SIZE(twl4030_predrivel_texts),
  189. twl4030_predrivel_texts);
  190. static const struct snd_kcontrol_new twl4030_dapm_predrivel_control =
  191. SOC_DAPM_ENUM("Route", twl4030_predrivel_enum);
  192. /* PreDrive Right */
  193. static const char *twl4030_predriver_texts[] =
  194. {"Off", "DACR1", "DACR2", "Invalid", "DACL2"};
  195. static const struct soc_enum twl4030_predriver_enum =
  196. SOC_ENUM_SINGLE(TWL4030_REG_PREDR_CTL, 1,
  197. ARRAY_SIZE(twl4030_predriver_texts),
  198. twl4030_predriver_texts);
  199. static const struct snd_kcontrol_new twl4030_dapm_predriver_control =
  200. SOC_DAPM_ENUM("Route", twl4030_predriver_enum);
  201. /* Headset Left */
  202. static const char *twl4030_hsol_texts[] =
  203. {"Off", "DACL1", "DACL2"};
  204. static const struct soc_enum twl4030_hsol_enum =
  205. SOC_ENUM_SINGLE(TWL4030_REG_HS_SEL, 1,
  206. ARRAY_SIZE(twl4030_hsol_texts),
  207. twl4030_hsol_texts);
  208. static const struct snd_kcontrol_new twl4030_dapm_hsol_control =
  209. SOC_DAPM_ENUM("Route", twl4030_hsol_enum);
  210. /* Headset Right */
  211. static const char *twl4030_hsor_texts[] =
  212. {"Off", "DACR1", "DACR2"};
  213. static const struct soc_enum twl4030_hsor_enum =
  214. SOC_ENUM_SINGLE(TWL4030_REG_HS_SEL, 4,
  215. ARRAY_SIZE(twl4030_hsor_texts),
  216. twl4030_hsor_texts);
  217. static const struct snd_kcontrol_new twl4030_dapm_hsor_control =
  218. SOC_DAPM_ENUM("Route", twl4030_hsor_enum);
  219. /* Carkit Left */
  220. static const char *twl4030_carkitl_texts[] =
  221. {"Off", "DACL1", "DACL2"};
  222. static const struct soc_enum twl4030_carkitl_enum =
  223. SOC_ENUM_SINGLE(TWL4030_REG_PRECKL_CTL, 1,
  224. ARRAY_SIZE(twl4030_carkitl_texts),
  225. twl4030_carkitl_texts);
  226. static const struct snd_kcontrol_new twl4030_dapm_carkitl_control =
  227. SOC_DAPM_ENUM("Route", twl4030_carkitl_enum);
  228. /* Carkit Right */
  229. static const char *twl4030_carkitr_texts[] =
  230. {"Off", "DACR1", "DACR2"};
  231. static const struct soc_enum twl4030_carkitr_enum =
  232. SOC_ENUM_SINGLE(TWL4030_REG_PRECKR_CTL, 1,
  233. ARRAY_SIZE(twl4030_carkitr_texts),
  234. twl4030_carkitr_texts);
  235. static const struct snd_kcontrol_new twl4030_dapm_carkitr_control =
  236. SOC_DAPM_ENUM("Route", twl4030_carkitr_enum);
  237. /* Handsfree Left */
  238. static const char *twl4030_handsfreel_texts[] =
  239. {"Voice", "DACL1", "DACL2", "DACR2"};
  240. static const struct soc_enum twl4030_handsfreel_enum =
  241. SOC_ENUM_SINGLE(TWL4030_REG_HFL_CTL, 0,
  242. ARRAY_SIZE(twl4030_handsfreel_texts),
  243. twl4030_handsfreel_texts);
  244. static const struct snd_kcontrol_new twl4030_dapm_handsfreel_control =
  245. SOC_DAPM_ENUM("Route", twl4030_handsfreel_enum);
  246. /* Handsfree Right */
  247. static const char *twl4030_handsfreer_texts[] =
  248. {"Voice", "DACR1", "DACR2", "DACL2"};
  249. static const struct soc_enum twl4030_handsfreer_enum =
  250. SOC_ENUM_SINGLE(TWL4030_REG_HFR_CTL, 0,
  251. ARRAY_SIZE(twl4030_handsfreer_texts),
  252. twl4030_handsfreer_texts);
  253. static const struct snd_kcontrol_new twl4030_dapm_handsfreer_control =
  254. SOC_DAPM_ENUM("Route", twl4030_handsfreer_enum);
  255. static int outmixer_event(struct snd_soc_dapm_widget *w,
  256. struct snd_kcontrol *kcontrol, int event)
  257. {
  258. struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
  259. int ret = 0;
  260. int val;
  261. switch (e->reg) {
  262. case TWL4030_REG_PREDL_CTL:
  263. case TWL4030_REG_PREDR_CTL:
  264. case TWL4030_REG_EAR_CTL:
  265. val = w->value >> e->shift_l;
  266. if (val == 3) {
  267. printk(KERN_WARNING
  268. "Invalid MUX setting for register 0x%02x (%d)\n",
  269. e->reg, val);
  270. ret = -1;
  271. }
  272. break;
  273. }
  274. return ret;
  275. }
  276. static int handsfree_event(struct snd_soc_dapm_widget *w,
  277. struct snd_kcontrol *kcontrol, int event)
  278. {
  279. struct soc_enum *e = (struct soc_enum *)w->kcontrols->private_value;
  280. unsigned char hs_ctl;
  281. hs_ctl = twl4030_read_reg_cache(w->codec, e->reg);
  282. if (hs_ctl & TWL4030_HF_CTL_REF_EN) {
  283. hs_ctl |= TWL4030_HF_CTL_RAMP_EN;
  284. twl4030_write(w->codec, e->reg, hs_ctl);
  285. hs_ctl |= TWL4030_HF_CTL_LOOP_EN;
  286. twl4030_write(w->codec, e->reg, hs_ctl);
  287. hs_ctl |= TWL4030_HF_CTL_HB_EN;
  288. twl4030_write(w->codec, e->reg, hs_ctl);
  289. } else {
  290. hs_ctl &= ~(TWL4030_HF_CTL_RAMP_EN | TWL4030_HF_CTL_LOOP_EN
  291. | TWL4030_HF_CTL_HB_EN);
  292. twl4030_write(w->codec, e->reg, hs_ctl);
  293. }
  294. return 0;
  295. }
  296. /*
  297. * Some of the gain controls in TWL (mostly those which are associated with
  298. * the outputs) are implemented in an interesting way:
  299. * 0x0 : Power down (mute)
  300. * 0x1 : 6dB
  301. * 0x2 : 0 dB
  302. * 0x3 : -6 dB
  303. * Inverting not going to help with these.
  304. * Custom volsw and volsw_2r get/put functions to handle these gain bits.
  305. */
  306. #define SOC_DOUBLE_TLV_TWL4030(xname, xreg, shift_left, shift_right, xmax,\
  307. xinvert, tlv_array) \
  308. { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
  309. .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
  310. SNDRV_CTL_ELEM_ACCESS_READWRITE,\
  311. .tlv.p = (tlv_array), \
  312. .info = snd_soc_info_volsw, \
  313. .get = snd_soc_get_volsw_twl4030, \
  314. .put = snd_soc_put_volsw_twl4030, \
  315. .private_value = (unsigned long)&(struct soc_mixer_control) \
  316. {.reg = xreg, .shift = shift_left, .rshift = shift_right,\
  317. .max = xmax, .invert = xinvert} }
  318. #define SOC_DOUBLE_R_TLV_TWL4030(xname, reg_left, reg_right, xshift, xmax,\
  319. xinvert, tlv_array) \
  320. { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
  321. .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
  322. SNDRV_CTL_ELEM_ACCESS_READWRITE,\
  323. .tlv.p = (tlv_array), \
  324. .info = snd_soc_info_volsw_2r, \
  325. .get = snd_soc_get_volsw_r2_twl4030,\
  326. .put = snd_soc_put_volsw_r2_twl4030, \
  327. .private_value = (unsigned long)&(struct soc_mixer_control) \
  328. {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
  329. .rshift = xshift, .max = xmax, .invert = xinvert} }
  330. #define SOC_SINGLE_TLV_TWL4030(xname, xreg, xshift, xmax, xinvert, tlv_array) \
  331. SOC_DOUBLE_TLV_TWL4030(xname, xreg, xshift, xshift, xmax, \
  332. xinvert, tlv_array)
  333. static int snd_soc_get_volsw_twl4030(struct snd_kcontrol *kcontrol,
  334. struct snd_ctl_elem_value *ucontrol)
  335. {
  336. struct soc_mixer_control *mc =
  337. (struct soc_mixer_control *)kcontrol->private_value;
  338. struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
  339. unsigned int reg = mc->reg;
  340. unsigned int shift = mc->shift;
  341. unsigned int rshift = mc->rshift;
  342. int max = mc->max;
  343. int mask = (1 << fls(max)) - 1;
  344. ucontrol->value.integer.value[0] =
  345. (snd_soc_read(codec, reg) >> shift) & mask;
  346. if (ucontrol->value.integer.value[0])
  347. ucontrol->value.integer.value[0] =
  348. max + 1 - ucontrol->value.integer.value[0];
  349. if (shift != rshift) {
  350. ucontrol->value.integer.value[1] =
  351. (snd_soc_read(codec, reg) >> rshift) & mask;
  352. if (ucontrol->value.integer.value[1])
  353. ucontrol->value.integer.value[1] =
  354. max + 1 - ucontrol->value.integer.value[1];
  355. }
  356. return 0;
  357. }
  358. static int snd_soc_put_volsw_twl4030(struct snd_kcontrol *kcontrol,
  359. struct snd_ctl_elem_value *ucontrol)
  360. {
  361. struct soc_mixer_control *mc =
  362. (struct soc_mixer_control *)kcontrol->private_value;
  363. struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
  364. unsigned int reg = mc->reg;
  365. unsigned int shift = mc->shift;
  366. unsigned int rshift = mc->rshift;
  367. int max = mc->max;
  368. int mask = (1 << fls(max)) - 1;
  369. unsigned short val, val2, val_mask;
  370. val = (ucontrol->value.integer.value[0] & mask);
  371. val_mask = mask << shift;
  372. if (val)
  373. val = max + 1 - val;
  374. val = val << shift;
  375. if (shift != rshift) {
  376. val2 = (ucontrol->value.integer.value[1] & mask);
  377. val_mask |= mask << rshift;
  378. if (val2)
  379. val2 = max + 1 - val2;
  380. val |= val2 << rshift;
  381. }
  382. return snd_soc_update_bits(codec, reg, val_mask, val);
  383. }
  384. static int snd_soc_get_volsw_r2_twl4030(struct snd_kcontrol *kcontrol,
  385. struct snd_ctl_elem_value *ucontrol)
  386. {
  387. struct soc_mixer_control *mc =
  388. (struct soc_mixer_control *)kcontrol->private_value;
  389. struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
  390. unsigned int reg = mc->reg;
  391. unsigned int reg2 = mc->rreg;
  392. unsigned int shift = mc->shift;
  393. int max = mc->max;
  394. int mask = (1<<fls(max))-1;
  395. ucontrol->value.integer.value[0] =
  396. (snd_soc_read(codec, reg) >> shift) & mask;
  397. ucontrol->value.integer.value[1] =
  398. (snd_soc_read(codec, reg2) >> shift) & mask;
  399. if (ucontrol->value.integer.value[0])
  400. ucontrol->value.integer.value[0] =
  401. max + 1 - ucontrol->value.integer.value[0];
  402. if (ucontrol->value.integer.value[1])
  403. ucontrol->value.integer.value[1] =
  404. max + 1 - ucontrol->value.integer.value[1];
  405. return 0;
  406. }
  407. static int snd_soc_put_volsw_r2_twl4030(struct snd_kcontrol *kcontrol,
  408. struct snd_ctl_elem_value *ucontrol)
  409. {
  410. struct soc_mixer_control *mc =
  411. (struct soc_mixer_control *)kcontrol->private_value;
  412. struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
  413. unsigned int reg = mc->reg;
  414. unsigned int reg2 = mc->rreg;
  415. unsigned int shift = mc->shift;
  416. int max = mc->max;
  417. int mask = (1 << fls(max)) - 1;
  418. int err;
  419. unsigned short val, val2, val_mask;
  420. val_mask = mask << shift;
  421. val = (ucontrol->value.integer.value[0] & mask);
  422. val2 = (ucontrol->value.integer.value[1] & mask);
  423. if (val)
  424. val = max + 1 - val;
  425. if (val2)
  426. val2 = max + 1 - val2;
  427. val = val << shift;
  428. val2 = val2 << shift;
  429. err = snd_soc_update_bits(codec, reg, val_mask, val);
  430. if (err < 0)
  431. return err;
  432. err = snd_soc_update_bits(codec, reg2, val_mask, val2);
  433. return err;
  434. }
  435. static int twl4030_get_left_input(struct snd_kcontrol *kcontrol,
  436. struct snd_ctl_elem_value *ucontrol)
  437. {
  438. struct snd_soc_codec *codec = kcontrol->private_data;
  439. u8 reg = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL);
  440. int result = 0;
  441. /* one bit must be set a time */
  442. reg &= TWL4030_CKMIC_EN | TWL4030_AUXL_EN | TWL4030_HSMIC_EN
  443. | TWL4030_MAINMIC_EN;
  444. if (reg != 0) {
  445. result++;
  446. while ((reg & 1) == 0) {
  447. result++;
  448. reg >>= 1;
  449. }
  450. }
  451. ucontrol->value.integer.value[0] = result;
  452. return 0;
  453. }
  454. static int twl4030_put_left_input(struct snd_kcontrol *kcontrol,
  455. struct snd_ctl_elem_value *ucontrol)
  456. {
  457. struct snd_soc_codec *codec = kcontrol->private_data;
  458. int value = ucontrol->value.integer.value[0];
  459. u8 anamicl, micbias, avadc_ctl;
  460. anamicl = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL);
  461. anamicl &= ~(TWL4030_CKMIC_EN | TWL4030_AUXL_EN | TWL4030_HSMIC_EN
  462. | TWL4030_MAINMIC_EN);
  463. micbias = twl4030_read_reg_cache(codec, TWL4030_REG_MICBIAS_CTL);
  464. micbias &= ~(TWL4030_HSMICBIAS_EN | TWL4030_MICBIAS1_EN);
  465. avadc_ctl = twl4030_read_reg_cache(codec, TWL4030_REG_AVADC_CTL);
  466. switch (value) {
  467. case 1:
  468. anamicl |= TWL4030_MAINMIC_EN;
  469. micbias |= TWL4030_MICBIAS1_EN;
  470. break;
  471. case 2:
  472. anamicl |= TWL4030_HSMIC_EN;
  473. micbias |= TWL4030_HSMICBIAS_EN;
  474. break;
  475. case 3:
  476. anamicl |= TWL4030_AUXL_EN;
  477. break;
  478. case 4:
  479. anamicl |= TWL4030_CKMIC_EN;
  480. break;
  481. default:
  482. break;
  483. }
  484. /* If some input is selected, enable amp and ADC */
  485. if (value != 0) {
  486. anamicl |= TWL4030_MICAMPL_EN;
  487. avadc_ctl |= TWL4030_ADCL_EN;
  488. } else {
  489. anamicl &= ~TWL4030_MICAMPL_EN;
  490. avadc_ctl &= ~TWL4030_ADCL_EN;
  491. }
  492. twl4030_write(codec, TWL4030_REG_ANAMICL, anamicl);
  493. twl4030_write(codec, TWL4030_REG_MICBIAS_CTL, micbias);
  494. twl4030_write(codec, TWL4030_REG_AVADC_CTL, avadc_ctl);
  495. return 1;
  496. }
  497. static int twl4030_get_right_input(struct snd_kcontrol *kcontrol,
  498. struct snd_ctl_elem_value *ucontrol)
  499. {
  500. struct snd_soc_codec *codec = kcontrol->private_data;
  501. u8 reg = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICR);
  502. int value = 0;
  503. reg &= TWL4030_SUBMIC_EN|TWL4030_AUXR_EN;
  504. switch (reg) {
  505. case TWL4030_SUBMIC_EN:
  506. value = 1;
  507. break;
  508. case TWL4030_AUXR_EN:
  509. value = 2;
  510. break;
  511. default:
  512. break;
  513. }
  514. ucontrol->value.integer.value[0] = value;
  515. return 0;
  516. }
  517. static int twl4030_put_right_input(struct snd_kcontrol *kcontrol,
  518. struct snd_ctl_elem_value *ucontrol)
  519. {
  520. struct snd_soc_codec *codec = kcontrol->private_data;
  521. int value = ucontrol->value.integer.value[0];
  522. u8 anamicr, micbias, avadc_ctl;
  523. anamicr = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICR);
  524. anamicr &= ~(TWL4030_SUBMIC_EN|TWL4030_AUXR_EN);
  525. micbias = twl4030_read_reg_cache(codec, TWL4030_REG_MICBIAS_CTL);
  526. micbias &= ~TWL4030_MICBIAS2_EN;
  527. avadc_ctl = twl4030_read_reg_cache(codec, TWL4030_REG_AVADC_CTL);
  528. switch (value) {
  529. case 1:
  530. anamicr |= TWL4030_SUBMIC_EN;
  531. micbias |= TWL4030_MICBIAS2_EN;
  532. break;
  533. case 2:
  534. anamicr |= TWL4030_AUXR_EN;
  535. break;
  536. default:
  537. break;
  538. }
  539. if (value != 0) {
  540. anamicr |= TWL4030_MICAMPR_EN;
  541. avadc_ctl |= TWL4030_ADCR_EN;
  542. } else {
  543. anamicr &= ~TWL4030_MICAMPR_EN;
  544. avadc_ctl &= ~TWL4030_ADCR_EN;
  545. }
  546. twl4030_write(codec, TWL4030_REG_ANAMICR, anamicr);
  547. twl4030_write(codec, TWL4030_REG_MICBIAS_CTL, micbias);
  548. twl4030_write(codec, TWL4030_REG_AVADC_CTL, avadc_ctl);
  549. return 1;
  550. }
  551. static const char *twl4030_left_in_sel[] = {
  552. "None",
  553. "Main Mic",
  554. "Headset Mic",
  555. "Line In",
  556. "Carkit Mic",
  557. };
  558. static const char *twl4030_right_in_sel[] = {
  559. "None",
  560. "Sub Mic",
  561. "Line In",
  562. };
  563. static const struct soc_enum twl4030_left_input_mux =
  564. SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(twl4030_left_in_sel),
  565. twl4030_left_in_sel);
  566. static const struct soc_enum twl4030_right_input_mux =
  567. SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(twl4030_right_in_sel),
  568. twl4030_right_in_sel);
  569. /*
  570. * FGAIN volume control:
  571. * from -62 to 0 dB in 1 dB steps (mute instead of -63 dB)
  572. */
  573. static DECLARE_TLV_DB_SCALE(digital_fine_tlv, -6300, 100, 1);
  574. /*
  575. * CGAIN volume control:
  576. * 0 dB to 12 dB in 6 dB steps
  577. * value 2 and 3 means 12 dB
  578. */
  579. static DECLARE_TLV_DB_SCALE(digital_coarse_tlv, 0, 600, 0);
  580. /*
  581. * Analog playback gain
  582. * -24 dB to 12 dB in 2 dB steps
  583. */
  584. static DECLARE_TLV_DB_SCALE(analog_tlv, -2400, 200, 0);
  585. /*
  586. * Gain controls tied to outputs
  587. * -6 dB to 6 dB in 6 dB steps (mute instead of -12)
  588. */
  589. static DECLARE_TLV_DB_SCALE(output_tvl, -1200, 600, 1);
  590. /*
  591. * Capture gain after the ADCs
  592. * from 0 dB to 31 dB in 1 dB steps
  593. */
  594. static DECLARE_TLV_DB_SCALE(digital_capture_tlv, 0, 100, 0);
  595. /*
  596. * Gain control for input amplifiers
  597. * 0 dB to 30 dB in 6 dB steps
  598. */
  599. static DECLARE_TLV_DB_SCALE(input_gain_tlv, 0, 600, 0);
  600. static const struct snd_kcontrol_new twl4030_snd_controls[] = {
  601. /* Common playback gain controls */
  602. SOC_DOUBLE_R_TLV("DAC1 Digital Fine Playback Volume",
  603. TWL4030_REG_ARXL1PGA, TWL4030_REG_ARXR1PGA,
  604. 0, 0x3f, 0, digital_fine_tlv),
  605. SOC_DOUBLE_R_TLV("DAC2 Digital Fine Playback Volume",
  606. TWL4030_REG_ARXL2PGA, TWL4030_REG_ARXR2PGA,
  607. 0, 0x3f, 0, digital_fine_tlv),
  608. SOC_DOUBLE_R_TLV("DAC1 Digital Coarse Playback Volume",
  609. TWL4030_REG_ARXL1PGA, TWL4030_REG_ARXR1PGA,
  610. 6, 0x2, 0, digital_coarse_tlv),
  611. SOC_DOUBLE_R_TLV("DAC2 Digital Coarse Playback Volume",
  612. TWL4030_REG_ARXL2PGA, TWL4030_REG_ARXR2PGA,
  613. 6, 0x2, 0, digital_coarse_tlv),
  614. SOC_DOUBLE_R_TLV("DAC1 Analog Playback Volume",
  615. TWL4030_REG_ARXL1_APGA_CTL, TWL4030_REG_ARXR1_APGA_CTL,
  616. 3, 0x12, 1, analog_tlv),
  617. SOC_DOUBLE_R_TLV("DAC2 Analog Playback Volume",
  618. TWL4030_REG_ARXL2_APGA_CTL, TWL4030_REG_ARXR2_APGA_CTL,
  619. 3, 0x12, 1, analog_tlv),
  620. SOC_DOUBLE_R("DAC1 Analog Playback Switch",
  621. TWL4030_REG_ARXL1_APGA_CTL, TWL4030_REG_ARXR1_APGA_CTL,
  622. 1, 1, 0),
  623. SOC_DOUBLE_R("DAC2 Analog Playback Switch",
  624. TWL4030_REG_ARXL2_APGA_CTL, TWL4030_REG_ARXR2_APGA_CTL,
  625. 1, 1, 0),
  626. /* Separate output gain controls */
  627. SOC_DOUBLE_R_TLV_TWL4030("PreDriv Playback Volume",
  628. TWL4030_REG_PREDL_CTL, TWL4030_REG_PREDR_CTL,
  629. 4, 3, 0, output_tvl),
  630. SOC_DOUBLE_TLV_TWL4030("Headset Playback Volume",
  631. TWL4030_REG_HS_GAIN_SET, 0, 2, 3, 0, output_tvl),
  632. SOC_DOUBLE_R_TLV_TWL4030("Carkit Playback Volume",
  633. TWL4030_REG_PRECKL_CTL, TWL4030_REG_PRECKR_CTL,
  634. 4, 3, 0, output_tvl),
  635. SOC_SINGLE_TLV_TWL4030("Earpiece Playback Volume",
  636. TWL4030_REG_EAR_CTL, 4, 3, 0, output_tvl),
  637. /* Common capture gain controls */
  638. SOC_DOUBLE_R_TLV("Capture Volume",
  639. TWL4030_REG_ATXL1PGA, TWL4030_REG_ATXR1PGA,
  640. 0, 0x1f, 0, digital_capture_tlv),
  641. SOC_DOUBLE_TLV("Input Boost Volume", TWL4030_REG_ANAMIC_GAIN,
  642. 0, 3, 5, 0, input_gain_tlv),
  643. /* Input source controls */
  644. SOC_ENUM_EXT("Left Input Source", twl4030_left_input_mux,
  645. twl4030_get_left_input, twl4030_put_left_input),
  646. SOC_ENUM_EXT("Right Input Source", twl4030_right_input_mux,
  647. twl4030_get_right_input, twl4030_put_right_input),
  648. };
  649. /* add non dapm controls */
  650. static int twl4030_add_controls(struct snd_soc_codec *codec)
  651. {
  652. int err, i;
  653. for (i = 0; i < ARRAY_SIZE(twl4030_snd_controls); i++) {
  654. err = snd_ctl_add(codec->card,
  655. snd_soc_cnew(&twl4030_snd_controls[i],
  656. codec, NULL));
  657. if (err < 0)
  658. return err;
  659. }
  660. return 0;
  661. }
  662. static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
  663. SND_SOC_DAPM_INPUT("INL"),
  664. SND_SOC_DAPM_INPUT("INR"),
  665. SND_SOC_DAPM_OUTPUT("OUTL"),
  666. SND_SOC_DAPM_OUTPUT("OUTR"),
  667. SND_SOC_DAPM_OUTPUT("EARPIECE"),
  668. SND_SOC_DAPM_OUTPUT("PREDRIVEL"),
  669. SND_SOC_DAPM_OUTPUT("PREDRIVER"),
  670. SND_SOC_DAPM_OUTPUT("HSOL"),
  671. SND_SOC_DAPM_OUTPUT("HSOR"),
  672. SND_SOC_DAPM_OUTPUT("CARKITL"),
  673. SND_SOC_DAPM_OUTPUT("CARKITR"),
  674. SND_SOC_DAPM_OUTPUT("HFL"),
  675. SND_SOC_DAPM_OUTPUT("HFR"),
  676. /* DACs */
  677. SND_SOC_DAPM_DAC("DAC Right1", "Right Front Playback",
  678. TWL4030_REG_AVDAC_CTL, 0, 0),
  679. SND_SOC_DAPM_DAC("DAC Left1", "Left Front Playback",
  680. TWL4030_REG_AVDAC_CTL, 1, 0),
  681. SND_SOC_DAPM_DAC("DAC Right2", "Right Rear Playback",
  682. TWL4030_REG_AVDAC_CTL, 2, 0),
  683. SND_SOC_DAPM_DAC("DAC Left2", "Left Rear Playback",
  684. TWL4030_REG_AVDAC_CTL, 3, 0),
  685. /* Analog PGAs */
  686. SND_SOC_DAPM_PGA("ARXR1_APGA", TWL4030_REG_ARXR1_APGA_CTL,
  687. 0, 0, NULL, 0),
  688. SND_SOC_DAPM_PGA("ARXL1_APGA", TWL4030_REG_ARXL1_APGA_CTL,
  689. 0, 0, NULL, 0),
  690. SND_SOC_DAPM_PGA("ARXR2_APGA", TWL4030_REG_ARXR2_APGA_CTL,
  691. 0, 0, NULL, 0),
  692. SND_SOC_DAPM_PGA("ARXL2_APGA", TWL4030_REG_ARXL2_APGA_CTL,
  693. 0, 0, NULL, 0),
  694. /* Output MUX controls */
  695. /* Earpiece */
  696. SND_SOC_DAPM_MUX_E("Earpiece Mux", SND_SOC_NOPM, 0, 0,
  697. &twl4030_dapm_earpiece_control, outmixer_event,
  698. SND_SOC_DAPM_PRE_REG),
  699. /* PreDrivL/R */
  700. SND_SOC_DAPM_MUX_E("PredriveL Mux", SND_SOC_NOPM, 0, 0,
  701. &twl4030_dapm_predrivel_control, outmixer_event,
  702. SND_SOC_DAPM_PRE_REG),
  703. SND_SOC_DAPM_MUX_E("PredriveR Mux", SND_SOC_NOPM, 0, 0,
  704. &twl4030_dapm_predriver_control, outmixer_event,
  705. SND_SOC_DAPM_PRE_REG),
  706. /* HeadsetL/R */
  707. SND_SOC_DAPM_MUX("HeadsetL Mux", SND_SOC_NOPM, 0, 0,
  708. &twl4030_dapm_hsol_control),
  709. SND_SOC_DAPM_MUX("HeadsetR Mux", SND_SOC_NOPM, 0, 0,
  710. &twl4030_dapm_hsor_control),
  711. /* CarkitL/R */
  712. SND_SOC_DAPM_MUX("CarkitL Mux", SND_SOC_NOPM, 0, 0,
  713. &twl4030_dapm_carkitl_control),
  714. SND_SOC_DAPM_MUX("CarkitR Mux", SND_SOC_NOPM, 0, 0,
  715. &twl4030_dapm_carkitr_control),
  716. /* HandsfreeL/R */
  717. SND_SOC_DAPM_MUX_E("HandsfreeL Mux", TWL4030_REG_HFL_CTL, 5, 0,
  718. &twl4030_dapm_handsfreel_control, handsfree_event,
  719. SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
  720. SND_SOC_DAPM_MUX_E("HandsfreeR Mux", TWL4030_REG_HFR_CTL, 5, 0,
  721. &twl4030_dapm_handsfreer_control, handsfree_event,
  722. SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
  723. SND_SOC_DAPM_ADC("ADCL", "Left Capture", SND_SOC_NOPM, 0, 0),
  724. SND_SOC_DAPM_ADC("ADCR", "Right Capture", SND_SOC_NOPM, 0, 0),
  725. };
  726. static const struct snd_soc_dapm_route intercon[] = {
  727. {"ARXL1_APGA", NULL, "DAC Left1"},
  728. {"ARXR1_APGA", NULL, "DAC Right1"},
  729. {"ARXL2_APGA", NULL, "DAC Left2"},
  730. {"ARXR2_APGA", NULL, "DAC Right2"},
  731. /* Internal playback routings */
  732. /* Earpiece */
  733. {"Earpiece Mux", "DACL1", "ARXL1_APGA"},
  734. {"Earpiece Mux", "DACL2", "ARXL2_APGA"},
  735. {"Earpiece Mux", "DACR1", "ARXR1_APGA"},
  736. /* PreDrivL */
  737. {"PredriveL Mux", "DACL1", "ARXL1_APGA"},
  738. {"PredriveL Mux", "DACL2", "ARXL2_APGA"},
  739. {"PredriveL Mux", "DACR2", "ARXR2_APGA"},
  740. /* PreDrivR */
  741. {"PredriveR Mux", "DACR1", "ARXR1_APGA"},
  742. {"PredriveR Mux", "DACR2", "ARXR2_APGA"},
  743. {"PredriveR Mux", "DACL2", "ARXL2_APGA"},
  744. /* HeadsetL */
  745. {"HeadsetL Mux", "DACL1", "ARXL1_APGA"},
  746. {"HeadsetL Mux", "DACL2", "ARXL2_APGA"},
  747. /* HeadsetR */
  748. {"HeadsetR Mux", "DACR1", "ARXR1_APGA"},
  749. {"HeadsetR Mux", "DACR2", "ARXR2_APGA"},
  750. /* CarkitL */
  751. {"CarkitL Mux", "DACL1", "ARXL1_APGA"},
  752. {"CarkitL Mux", "DACL2", "ARXL2_APGA"},
  753. /* CarkitR */
  754. {"CarkitR Mux", "DACR1", "ARXR1_APGA"},
  755. {"CarkitR Mux", "DACR2", "ARXR2_APGA"},
  756. /* HandsfreeL */
  757. {"HandsfreeL Mux", "DACL1", "ARXL1_APGA"},
  758. {"HandsfreeL Mux", "DACL2", "ARXL2_APGA"},
  759. {"HandsfreeL Mux", "DACR2", "ARXR2_APGA"},
  760. /* HandsfreeR */
  761. {"HandsfreeR Mux", "DACR1", "ARXR1_APGA"},
  762. {"HandsfreeR Mux", "DACR2", "ARXR2_APGA"},
  763. {"HandsfreeR Mux", "DACL2", "ARXL2_APGA"},
  764. /* outputs */
  765. {"OUTL", NULL, "ARXL2_APGA"},
  766. {"OUTR", NULL, "ARXR2_APGA"},
  767. {"EARPIECE", NULL, "Earpiece Mux"},
  768. {"PREDRIVEL", NULL, "PredriveL Mux"},
  769. {"PREDRIVER", NULL, "PredriveR Mux"},
  770. {"HSOL", NULL, "HeadsetL Mux"},
  771. {"HSOR", NULL, "HeadsetR Mux"},
  772. {"CARKITL", NULL, "CarkitL Mux"},
  773. {"CARKITR", NULL, "CarkitR Mux"},
  774. {"HFL", NULL, "HandsfreeL Mux"},
  775. {"HFR", NULL, "HandsfreeR Mux"},
  776. /* inputs */
  777. {"ADCL", NULL, "INL"},
  778. {"ADCR", NULL, "INR"},
  779. };
  780. static int twl4030_add_widgets(struct snd_soc_codec *codec)
  781. {
  782. snd_soc_dapm_new_controls(codec, twl4030_dapm_widgets,
  783. ARRAY_SIZE(twl4030_dapm_widgets));
  784. snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
  785. snd_soc_dapm_new_widgets(codec);
  786. return 0;
  787. }
  788. static void twl4030_power_up(struct snd_soc_codec *codec)
  789. {
  790. u8 anamicl, regmisc1, byte, popn;
  791. int i = 0;
  792. /* set CODECPDZ to turn on codec */
  793. twl4030_set_codecpdz(codec);
  794. /* initiate offset cancellation */
  795. anamicl = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL);
  796. twl4030_write(codec, TWL4030_REG_ANAMICL,
  797. anamicl | TWL4030_CNCL_OFFSET_START);
  798. /* wait for offset cancellation to complete */
  799. do {
  800. /* this takes a little while, so don't slam i2c */
  801. udelay(2000);
  802. twl4030_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte,
  803. TWL4030_REG_ANAMICL);
  804. } while ((i++ < 100) &&
  805. ((byte & TWL4030_CNCL_OFFSET_START) ==
  806. TWL4030_CNCL_OFFSET_START));
  807. /* anti-pop when changing analog gain */
  808. regmisc1 = twl4030_read_reg_cache(codec, TWL4030_REG_MISC_SET_1);
  809. twl4030_write(codec, TWL4030_REG_MISC_SET_1,
  810. regmisc1 | TWL4030_SMOOTH_ANAVOL_EN);
  811. /* toggle CODECPDZ as per TRM */
  812. twl4030_clear_codecpdz(codec);
  813. twl4030_set_codecpdz(codec);
  814. /* program anti-pop with bias ramp delay */
  815. popn = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
  816. popn &= TWL4030_RAMP_DELAY;
  817. popn |= TWL4030_RAMP_DELAY_645MS;
  818. twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn);
  819. popn |= TWL4030_VMID_EN;
  820. twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn);
  821. /* enable anti-pop ramp */
  822. popn |= TWL4030_RAMP_EN;
  823. twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn);
  824. }
  825. static void twl4030_power_down(struct snd_soc_codec *codec)
  826. {
  827. u8 popn;
  828. /* disable anti-pop ramp */
  829. popn = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
  830. popn &= ~TWL4030_RAMP_EN;
  831. twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn);
  832. /* disable bias out */
  833. popn &= ~TWL4030_VMID_EN;
  834. twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn);
  835. /* power down */
  836. twl4030_clear_codecpdz(codec);
  837. }
  838. static int twl4030_set_bias_level(struct snd_soc_codec *codec,
  839. enum snd_soc_bias_level level)
  840. {
  841. switch (level) {
  842. case SND_SOC_BIAS_ON:
  843. twl4030_power_up(codec);
  844. break;
  845. case SND_SOC_BIAS_PREPARE:
  846. /* TODO: develop a twl4030_prepare function */
  847. break;
  848. case SND_SOC_BIAS_STANDBY:
  849. /* TODO: develop a twl4030_standby function */
  850. twl4030_power_down(codec);
  851. break;
  852. case SND_SOC_BIAS_OFF:
  853. twl4030_power_down(codec);
  854. break;
  855. }
  856. codec->bias_level = level;
  857. return 0;
  858. }
  859. static int twl4030_hw_params(struct snd_pcm_substream *substream,
  860. struct snd_pcm_hw_params *params,
  861. struct snd_soc_dai *dai)
  862. {
  863. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  864. struct snd_soc_device *socdev = rtd->socdev;
  865. struct snd_soc_codec *codec = socdev->codec;
  866. u8 mode, old_mode, format, old_format;
  867. /* bit rate */
  868. old_mode = twl4030_read_reg_cache(codec,
  869. TWL4030_REG_CODEC_MODE) & ~TWL4030_CODECPDZ;
  870. mode = old_mode & ~TWL4030_APLL_RATE;
  871. switch (params_rate(params)) {
  872. case 8000:
  873. mode |= TWL4030_APLL_RATE_8000;
  874. break;
  875. case 11025:
  876. mode |= TWL4030_APLL_RATE_11025;
  877. break;
  878. case 12000:
  879. mode |= TWL4030_APLL_RATE_12000;
  880. break;
  881. case 16000:
  882. mode |= TWL4030_APLL_RATE_16000;
  883. break;
  884. case 22050:
  885. mode |= TWL4030_APLL_RATE_22050;
  886. break;
  887. case 24000:
  888. mode |= TWL4030_APLL_RATE_24000;
  889. break;
  890. case 32000:
  891. mode |= TWL4030_APLL_RATE_32000;
  892. break;
  893. case 44100:
  894. mode |= TWL4030_APLL_RATE_44100;
  895. break;
  896. case 48000:
  897. mode |= TWL4030_APLL_RATE_48000;
  898. break;
  899. default:
  900. printk(KERN_ERR "TWL4030 hw params: unknown rate %d\n",
  901. params_rate(params));
  902. return -EINVAL;
  903. }
  904. if (mode != old_mode) {
  905. /* change rate and set CODECPDZ */
  906. twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
  907. twl4030_set_codecpdz(codec);
  908. }
  909. /* sample size */
  910. old_format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF);
  911. format = old_format;
  912. format &= ~TWL4030_DATA_WIDTH;
  913. switch (params_format(params)) {
  914. case SNDRV_PCM_FORMAT_S16_LE:
  915. format |= TWL4030_DATA_WIDTH_16S_16W;
  916. break;
  917. case SNDRV_PCM_FORMAT_S24_LE:
  918. format |= TWL4030_DATA_WIDTH_32S_24W;
  919. break;
  920. default:
  921. printk(KERN_ERR "TWL4030 hw params: unknown format %d\n",
  922. params_format(params));
  923. return -EINVAL;
  924. }
  925. if (format != old_format) {
  926. /* clear CODECPDZ before changing format (codec requirement) */
  927. twl4030_clear_codecpdz(codec);
  928. /* change format */
  929. twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
  930. /* set CODECPDZ afterwards */
  931. twl4030_set_codecpdz(codec);
  932. }
  933. return 0;
  934. }
  935. static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai,
  936. int clk_id, unsigned int freq, int dir)
  937. {
  938. struct snd_soc_codec *codec = codec_dai->codec;
  939. u8 infreq;
  940. switch (freq) {
  941. case 19200000:
  942. infreq = TWL4030_APLL_INFREQ_19200KHZ;
  943. break;
  944. case 26000000:
  945. infreq = TWL4030_APLL_INFREQ_26000KHZ;
  946. break;
  947. case 38400000:
  948. infreq = TWL4030_APLL_INFREQ_38400KHZ;
  949. break;
  950. default:
  951. printk(KERN_ERR "TWL4030 set sysclk: unknown rate %d\n",
  952. freq);
  953. return -EINVAL;
  954. }
  955. infreq |= TWL4030_APLL_EN;
  956. twl4030_write(codec, TWL4030_REG_APLL_CTL, infreq);
  957. return 0;
  958. }
  959. static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai,
  960. unsigned int fmt)
  961. {
  962. struct snd_soc_codec *codec = codec_dai->codec;
  963. u8 old_format, format;
  964. /* get format */
  965. old_format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF);
  966. format = old_format;
  967. /* set master/slave audio interface */
  968. switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
  969. case SND_SOC_DAIFMT_CBM_CFM:
  970. format &= ~(TWL4030_AIF_SLAVE_EN);
  971. format &= ~(TWL4030_CLK256FS_EN);
  972. break;
  973. case SND_SOC_DAIFMT_CBS_CFS:
  974. format |= TWL4030_AIF_SLAVE_EN;
  975. format |= TWL4030_CLK256FS_EN;
  976. break;
  977. default:
  978. return -EINVAL;
  979. }
  980. /* interface format */
  981. format &= ~TWL4030_AIF_FORMAT;
  982. switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
  983. case SND_SOC_DAIFMT_I2S:
  984. format |= TWL4030_AIF_FORMAT_CODEC;
  985. break;
  986. default:
  987. return -EINVAL;
  988. }
  989. if (format != old_format) {
  990. /* clear CODECPDZ before changing format (codec requirement) */
  991. twl4030_clear_codecpdz(codec);
  992. /* change format */
  993. twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
  994. /* set CODECPDZ afterwards */
  995. twl4030_set_codecpdz(codec);
  996. }
  997. return 0;
  998. }
  999. #define TWL4030_RATES (SNDRV_PCM_RATE_8000_48000)
  1000. #define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE)
  1001. struct snd_soc_dai twl4030_dai = {
  1002. .name = "twl4030",
  1003. .playback = {
  1004. .stream_name = "Playback",
  1005. .channels_min = 2,
  1006. .channels_max = 2,
  1007. .rates = TWL4030_RATES,
  1008. .formats = TWL4030_FORMATS,},
  1009. .capture = {
  1010. .stream_name = "Capture",
  1011. .channels_min = 2,
  1012. .channels_max = 2,
  1013. .rates = TWL4030_RATES,
  1014. .formats = TWL4030_FORMATS,},
  1015. .ops = {
  1016. .hw_params = twl4030_hw_params,
  1017. .set_sysclk = twl4030_set_dai_sysclk,
  1018. .set_fmt = twl4030_set_dai_fmt,
  1019. }
  1020. };
  1021. EXPORT_SYMBOL_GPL(twl4030_dai);
  1022. static int twl4030_suspend(struct platform_device *pdev, pm_message_t state)
  1023. {
  1024. struct snd_soc_device *socdev = platform_get_drvdata(pdev);
  1025. struct snd_soc_codec *codec = socdev->codec;
  1026. twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
  1027. return 0;
  1028. }
  1029. static int twl4030_resume(struct platform_device *pdev)
  1030. {
  1031. struct snd_soc_device *socdev = platform_get_drvdata(pdev);
  1032. struct snd_soc_codec *codec = socdev->codec;
  1033. twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
  1034. twl4030_set_bias_level(codec, codec->suspend_bias_level);
  1035. return 0;
  1036. }
  1037. /*
  1038. * initialize the driver
  1039. * register the mixer and dsp interfaces with the kernel
  1040. */
  1041. static int twl4030_init(struct snd_soc_device *socdev)
  1042. {
  1043. struct snd_soc_codec *codec = socdev->codec;
  1044. int ret = 0;
  1045. printk(KERN_INFO "TWL4030 Audio Codec init \n");
  1046. codec->name = "twl4030";
  1047. codec->owner = THIS_MODULE;
  1048. codec->read = twl4030_read_reg_cache;
  1049. codec->write = twl4030_write;
  1050. codec->set_bias_level = twl4030_set_bias_level;
  1051. codec->dai = &twl4030_dai;
  1052. codec->num_dai = 1;
  1053. codec->reg_cache_size = sizeof(twl4030_reg);
  1054. codec->reg_cache = kmemdup(twl4030_reg, sizeof(twl4030_reg),
  1055. GFP_KERNEL);
  1056. if (codec->reg_cache == NULL)
  1057. return -ENOMEM;
  1058. /* register pcms */
  1059. ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
  1060. if (ret < 0) {
  1061. printk(KERN_ERR "twl4030: failed to create pcms\n");
  1062. goto pcm_err;
  1063. }
  1064. twl4030_init_chip(codec);
  1065. /* power on device */
  1066. twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
  1067. twl4030_add_controls(codec);
  1068. twl4030_add_widgets(codec);
  1069. ret = snd_soc_init_card(socdev);
  1070. if (ret < 0) {
  1071. printk(KERN_ERR "twl4030: failed to register card\n");
  1072. goto card_err;
  1073. }
  1074. return ret;
  1075. card_err:
  1076. snd_soc_free_pcms(socdev);
  1077. snd_soc_dapm_free(socdev);
  1078. pcm_err:
  1079. kfree(codec->reg_cache);
  1080. return ret;
  1081. }
  1082. static struct snd_soc_device *twl4030_socdev;
  1083. static int twl4030_probe(struct platform_device *pdev)
  1084. {
  1085. struct snd_soc_device *socdev = platform_get_drvdata(pdev);
  1086. struct snd_soc_codec *codec;
  1087. codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
  1088. if (codec == NULL)
  1089. return -ENOMEM;
  1090. socdev->codec = codec;
  1091. mutex_init(&codec->mutex);
  1092. INIT_LIST_HEAD(&codec->dapm_widgets);
  1093. INIT_LIST_HEAD(&codec->dapm_paths);
  1094. twl4030_socdev = socdev;
  1095. twl4030_init(socdev);
  1096. return 0;
  1097. }
  1098. static int twl4030_remove(struct platform_device *pdev)
  1099. {
  1100. struct snd_soc_device *socdev = platform_get_drvdata(pdev);
  1101. struct snd_soc_codec *codec = socdev->codec;
  1102. printk(KERN_INFO "TWL4030 Audio Codec remove\n");
  1103. kfree(codec);
  1104. return 0;
  1105. }
  1106. struct snd_soc_codec_device soc_codec_dev_twl4030 = {
  1107. .probe = twl4030_probe,
  1108. .remove = twl4030_remove,
  1109. .suspend = twl4030_suspend,
  1110. .resume = twl4030_resume,
  1111. };
  1112. EXPORT_SYMBOL_GPL(soc_codec_dev_twl4030);
  1113. static int __init twl4030_modinit(void)
  1114. {
  1115. return snd_soc_register_dai(&twl4030_dai);
  1116. }
  1117. module_init(twl4030_modinit);
  1118. static void __exit twl4030_exit(void)
  1119. {
  1120. snd_soc_unregister_dai(&twl4030_dai);
  1121. }
  1122. module_exit(twl4030_exit);
  1123. MODULE_DESCRIPTION("ASoC TWL4030 codec driver");
  1124. MODULE_AUTHOR("Steve Sakoman");
  1125. MODULE_LICENSE("GPL");