tfa9879.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. /*
  2. * tfa9879.c -- driver for NXP Semiconductors TFA9879
  3. *
  4. * Copyright (C) 2014 Axentia Technologies AB
  5. * Author: Peter Rosin <peda@axentia.se>
  6. *
  7. * This program is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU General Public License as published by the
  9. * Free Software Foundation; either version 2 of the License, or (at your
  10. * option) any later version.
  11. *
  12. */
  13. #include <linux/module.h>
  14. #include <linux/init.h>
  15. #include <linux/i2c.h>
  16. #include <linux/regmap.h>
  17. #include <sound/soc.h>
  18. #include <sound/tlv.h>
  19. #include <sound/pcm_params.h>
  20. #include "tfa9879.h"
  21. struct tfa9879_priv {
  22. struct regmap *regmap;
  23. int lsb_justified;
  24. };
  25. static int tfa9879_hw_params(struct snd_pcm_substream *substream,
  26. struct snd_pcm_hw_params *params,
  27. struct snd_soc_dai *dai)
  28. {
  29. struct snd_soc_codec *codec = dai->codec;
  30. struct tfa9879_priv *tfa9879 = snd_soc_codec_get_drvdata(codec);
  31. int fs;
  32. int i2s_set = 0;
  33. switch (params_rate(params)) {
  34. case 8000:
  35. fs = TFA9879_I2S_FS_8000;
  36. break;
  37. case 11025:
  38. fs = TFA9879_I2S_FS_11025;
  39. break;
  40. case 12000:
  41. fs = TFA9879_I2S_FS_12000;
  42. break;
  43. case 16000:
  44. fs = TFA9879_I2S_FS_16000;
  45. break;
  46. case 22050:
  47. fs = TFA9879_I2S_FS_22050;
  48. break;
  49. case 24000:
  50. fs = TFA9879_I2S_FS_24000;
  51. break;
  52. case 32000:
  53. fs = TFA9879_I2S_FS_32000;
  54. break;
  55. case 44100:
  56. fs = TFA9879_I2S_FS_44100;
  57. break;
  58. case 48000:
  59. fs = TFA9879_I2S_FS_48000;
  60. break;
  61. case 64000:
  62. fs = TFA9879_I2S_FS_64000;
  63. break;
  64. case 88200:
  65. fs = TFA9879_I2S_FS_88200;
  66. break;
  67. case 96000:
  68. fs = TFA9879_I2S_FS_96000;
  69. break;
  70. default:
  71. return -EINVAL;
  72. }
  73. switch (params_width(params)) {
  74. case 16:
  75. i2s_set = TFA9879_I2S_SET_LSB_J_16;
  76. break;
  77. case 24:
  78. i2s_set = TFA9879_I2S_SET_LSB_J_24;
  79. break;
  80. default:
  81. return -EINVAL;
  82. }
  83. if (tfa9879->lsb_justified)
  84. snd_soc_update_bits(codec, TFA9879_SERIAL_INTERFACE_1,
  85. TFA9879_I2S_SET_MASK,
  86. i2s_set << TFA9879_I2S_SET_SHIFT);
  87. snd_soc_update_bits(codec, TFA9879_SERIAL_INTERFACE_1,
  88. TFA9879_I2S_FS_MASK,
  89. fs << TFA9879_I2S_FS_SHIFT);
  90. return 0;
  91. }
  92. static int tfa9879_digital_mute(struct snd_soc_dai *dai, int mute)
  93. {
  94. struct snd_soc_codec *codec = dai->codec;
  95. snd_soc_update_bits(codec, TFA9879_MISC_CONTROL,
  96. TFA9879_S_MUTE_MASK,
  97. !!mute << TFA9879_S_MUTE_SHIFT);
  98. return 0;
  99. }
  100. static int tfa9879_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
  101. {
  102. struct snd_soc_codec *codec = dai->codec;
  103. struct tfa9879_priv *tfa9879 = snd_soc_codec_get_drvdata(codec);
  104. int i2s_set;
  105. int sck_pol;
  106. switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
  107. case SND_SOC_DAIFMT_CBS_CFS:
  108. break;
  109. default:
  110. return -EINVAL;
  111. }
  112. switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
  113. case SND_SOC_DAIFMT_NB_NF:
  114. sck_pol = TFA9879_SCK_POL_NORMAL;
  115. break;
  116. case SND_SOC_DAIFMT_IB_NF:
  117. sck_pol = TFA9879_SCK_POL_INVERSE;
  118. break;
  119. default:
  120. return -EINVAL;
  121. }
  122. switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
  123. case SND_SOC_DAIFMT_I2S:
  124. tfa9879->lsb_justified = 0;
  125. i2s_set = TFA9879_I2S_SET_I2S_24;
  126. break;
  127. case SND_SOC_DAIFMT_LEFT_J:
  128. tfa9879->lsb_justified = 0;
  129. i2s_set = TFA9879_I2S_SET_MSB_J_24;
  130. break;
  131. case SND_SOC_DAIFMT_RIGHT_J:
  132. tfa9879->lsb_justified = 1;
  133. i2s_set = TFA9879_I2S_SET_LSB_J_24;
  134. break;
  135. default:
  136. return -EINVAL;
  137. }
  138. snd_soc_update_bits(codec, TFA9879_SERIAL_INTERFACE_1,
  139. TFA9879_SCK_POL_MASK,
  140. sck_pol << TFA9879_SCK_POL_SHIFT);
  141. snd_soc_update_bits(codec, TFA9879_SERIAL_INTERFACE_1,
  142. TFA9879_I2S_SET_MASK,
  143. i2s_set << TFA9879_I2S_SET_SHIFT);
  144. return 0;
  145. }
  146. static const struct reg_default tfa9879_regs[] = {
  147. { TFA9879_DEVICE_CONTROL, 0x0000 }, /* 0x00 */
  148. { TFA9879_SERIAL_INTERFACE_1, 0x0a18 }, /* 0x01 */
  149. { TFA9879_PCM_IOM2_FORMAT_1, 0x0007 }, /* 0x02 */
  150. { TFA9879_SERIAL_INTERFACE_2, 0x0a18 }, /* 0x03 */
  151. { TFA9879_PCM_IOM2_FORMAT_2, 0x0007 }, /* 0x04 */
  152. { TFA9879_EQUALIZER_A1, 0x59dd }, /* 0x05 */
  153. { TFA9879_EQUALIZER_A2, 0xc63e }, /* 0x06 */
  154. { TFA9879_EQUALIZER_B1, 0x651a }, /* 0x07 */
  155. { TFA9879_EQUALIZER_B2, 0xe53e }, /* 0x08 */
  156. { TFA9879_EQUALIZER_C1, 0x4616 }, /* 0x09 */
  157. { TFA9879_EQUALIZER_C2, 0xd33e }, /* 0x0a */
  158. { TFA9879_EQUALIZER_D1, 0x4df3 }, /* 0x0b */
  159. { TFA9879_EQUALIZER_D2, 0xea3e }, /* 0x0c */
  160. { TFA9879_EQUALIZER_E1, 0x5ee0 }, /* 0x0d */
  161. { TFA9879_EQUALIZER_E2, 0xf93e }, /* 0x0e */
  162. { TFA9879_BYPASS_CONTROL, 0x0093 }, /* 0x0f */
  163. { TFA9879_DYNAMIC_RANGE_COMPR, 0x92ba }, /* 0x10 */
  164. { TFA9879_BASS_TREBLE, 0x12a5 }, /* 0x11 */
  165. { TFA9879_HIGH_PASS_FILTER, 0x0004 }, /* 0x12 */
  166. { TFA9879_VOLUME_CONTROL, 0x10bd }, /* 0x13 */
  167. { TFA9879_MISC_CONTROL, 0x0000 }, /* 0x14 */
  168. };
  169. static bool tfa9879_volatile_reg(struct device *dev, unsigned int reg)
  170. {
  171. return reg == TFA9879_MISC_STATUS;
  172. }
  173. static const DECLARE_TLV_DB_SCALE(volume_tlv, -7050, 50, 1);
  174. static const DECLARE_TLV_DB_SCALE(tb_gain_tlv, -1800, 200, 0);
  175. static const char * const tb_freq_text[] = {
  176. "Low", "Mid", "High"
  177. };
  178. static const struct soc_enum treble_freq_enum =
  179. SOC_ENUM_SINGLE(TFA9879_BASS_TREBLE, TFA9879_F_TRBLE_SHIFT,
  180. ARRAY_SIZE(tb_freq_text), tb_freq_text);
  181. static const struct soc_enum bass_freq_enum =
  182. SOC_ENUM_SINGLE(TFA9879_BASS_TREBLE, TFA9879_F_BASS_SHIFT,
  183. ARRAY_SIZE(tb_freq_text), tb_freq_text);
  184. static const struct snd_kcontrol_new tfa9879_controls[] = {
  185. SOC_SINGLE_TLV("PCM Playback Volume", TFA9879_VOLUME_CONTROL,
  186. TFA9879_VOL_SHIFT, 0xbd, 1, volume_tlv),
  187. SOC_SINGLE_TLV("Treble Volume", TFA9879_BASS_TREBLE,
  188. TFA9879_G_TRBLE_SHIFT, 18, 0, tb_gain_tlv),
  189. SOC_SINGLE_TLV("Bass Volume", TFA9879_BASS_TREBLE,
  190. TFA9879_G_BASS_SHIFT, 18, 0, tb_gain_tlv),
  191. SOC_ENUM("Treble Corner Freq", treble_freq_enum),
  192. SOC_ENUM("Bass Corner Freq", bass_freq_enum),
  193. };
  194. static const struct snd_soc_dapm_widget tfa9879_dapm_widgets[] = {
  195. SND_SOC_DAPM_AIF_IN("AIFINL", "Playback", 0, SND_SOC_NOPM, 0, 0),
  196. SND_SOC_DAPM_AIF_IN("AIFINR", "Playback", 1, SND_SOC_NOPM, 0, 0),
  197. SND_SOC_DAPM_DAC("DAC", NULL, TFA9879_DEVICE_CONTROL, TFA9879_OPMODE_SHIFT, 0),
  198. SND_SOC_DAPM_OUTPUT("LINEOUT"),
  199. SND_SOC_DAPM_SUPPLY("POWER", TFA9879_DEVICE_CONTROL, TFA9879_POWERUP_SHIFT, 0,
  200. NULL, 0),
  201. };
  202. static const struct snd_soc_dapm_route tfa9879_dapm_routes[] = {
  203. { "DAC", NULL, "AIFINL" },
  204. { "DAC", NULL, "AIFINR" },
  205. { "LINEOUT", NULL, "DAC" },
  206. { "DAC", NULL, "POWER" },
  207. };
  208. static const struct snd_soc_codec_driver tfa9879_codec = {
  209. .component_driver = {
  210. .controls = tfa9879_controls,
  211. .num_controls = ARRAY_SIZE(tfa9879_controls),
  212. .dapm_widgets = tfa9879_dapm_widgets,
  213. .num_dapm_widgets = ARRAY_SIZE(tfa9879_dapm_widgets),
  214. .dapm_routes = tfa9879_dapm_routes,
  215. .num_dapm_routes = ARRAY_SIZE(tfa9879_dapm_routes),
  216. },
  217. };
  218. static const struct regmap_config tfa9879_regmap = {
  219. .reg_bits = 8,
  220. .val_bits = 16,
  221. .volatile_reg = tfa9879_volatile_reg,
  222. .max_register = TFA9879_MISC_STATUS,
  223. .reg_defaults = tfa9879_regs,
  224. .num_reg_defaults = ARRAY_SIZE(tfa9879_regs),
  225. .cache_type = REGCACHE_RBTREE,
  226. };
  227. static const struct snd_soc_dai_ops tfa9879_dai_ops = {
  228. .hw_params = tfa9879_hw_params,
  229. .digital_mute = tfa9879_digital_mute,
  230. .set_fmt = tfa9879_set_fmt,
  231. };
  232. #define TFA9879_RATES SNDRV_PCM_RATE_8000_96000
  233. #define TFA9879_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
  234. SNDRV_PCM_FMTBIT_S24_LE)
  235. static struct snd_soc_dai_driver tfa9879_dai = {
  236. .name = "tfa9879-hifi",
  237. .playback = {
  238. .stream_name = "Playback",
  239. .channels_min = 2,
  240. .channels_max = 2,
  241. .rates = TFA9879_RATES,
  242. .formats = TFA9879_FORMATS, },
  243. .ops = &tfa9879_dai_ops,
  244. };
  245. static int tfa9879_i2c_probe(struct i2c_client *i2c,
  246. const struct i2c_device_id *id)
  247. {
  248. struct tfa9879_priv *tfa9879;
  249. int i;
  250. tfa9879 = devm_kzalloc(&i2c->dev, sizeof(*tfa9879), GFP_KERNEL);
  251. if (!tfa9879)
  252. return -ENOMEM;
  253. i2c_set_clientdata(i2c, tfa9879);
  254. tfa9879->regmap = devm_regmap_init_i2c(i2c, &tfa9879_regmap);
  255. if (IS_ERR(tfa9879->regmap))
  256. return PTR_ERR(tfa9879->regmap);
  257. /* Ensure the device is in reset state */
  258. for (i = 0; i < ARRAY_SIZE(tfa9879_regs); i++)
  259. regmap_write(tfa9879->regmap,
  260. tfa9879_regs[i].reg, tfa9879_regs[i].def);
  261. return snd_soc_register_codec(&i2c->dev, &tfa9879_codec,
  262. &tfa9879_dai, 1);
  263. }
  264. static int tfa9879_i2c_remove(struct i2c_client *client)
  265. {
  266. snd_soc_unregister_codec(&client->dev);
  267. return 0;
  268. }
  269. static const struct i2c_device_id tfa9879_i2c_id[] = {
  270. { "tfa9879", 0 },
  271. { }
  272. };
  273. MODULE_DEVICE_TABLE(i2c, tfa9879_i2c_id);
  274. static struct i2c_driver tfa9879_i2c_driver = {
  275. .driver = {
  276. .name = "tfa9879",
  277. },
  278. .probe = tfa9879_i2c_probe,
  279. .remove = tfa9879_i2c_remove,
  280. .id_table = tfa9879_i2c_id,
  281. };
  282. module_i2c_driver(tfa9879_i2c_driver);
  283. MODULE_DESCRIPTION("ASoC NXP Semiconductors TFA9879 driver");
  284. MODULE_AUTHOR("Peter Rosin <peda@axentia.se>");
  285. MODULE_LICENSE("GPL");