hdmi-codec.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * ALSA SoC codec for HDMI encoder drivers
  4. * Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com/
  5. * Author: Jyri Sarha <jsarha@ti.com>
  6. */
  7. #include <linux/module.h>
  8. #include <linux/string.h>
  9. #include <sound/core.h>
  10. #include <sound/jack.h>
  11. #include <sound/pcm.h>
  12. #include <sound/pcm_params.h>
  13. #include <sound/soc.h>
  14. #include <sound/tlv.h>
  15. #include <sound/pcm_drm_eld.h>
  16. #include <sound/hdmi-codec.h>
  17. #include <sound/pcm_iec958.h>
  18. #include <drm/drm_crtc.h> /* This is only to get MAX_ELD_BYTES */
  19. #define HDMI_CODEC_CHMAP_IDX_UNKNOWN -1
  20. struct hdmi_codec_channel_map_table {
  21. unsigned char map; /* ALSA API channel map position */
  22. unsigned long spk_mask; /* speaker position bit mask */
  23. };
  24. /*
  25. * CEA speaker placement for HDMI 1.4:
  26. *
  27. * FL FLC FC FRC FR FRW
  28. *
  29. * LFE
  30. *
  31. * RL RLC RC RRC RR
  32. *
  33. * Speaker placement has to be extended to support HDMI 2.0
  34. */
  35. enum hdmi_codec_cea_spk_placement {
  36. FL = BIT(0), /* Front Left */
  37. FC = BIT(1), /* Front Center */
  38. FR = BIT(2), /* Front Right */
  39. FLC = BIT(3), /* Front Left Center */
  40. FRC = BIT(4), /* Front Right Center */
  41. RL = BIT(5), /* Rear Left */
  42. RC = BIT(6), /* Rear Center */
  43. RR = BIT(7), /* Rear Right */
  44. RLC = BIT(8), /* Rear Left Center */
  45. RRC = BIT(9), /* Rear Right Center */
  46. LFE = BIT(10), /* Low Frequency Effect */
  47. };
  48. /*
  49. * cea Speaker allocation structure
  50. */
  51. struct hdmi_codec_cea_spk_alloc {
  52. const int ca_id;
  53. unsigned int n_ch;
  54. unsigned long mask;
  55. };
  56. /* Channel maps stereo HDMI */
  57. static const struct snd_pcm_chmap_elem hdmi_codec_stereo_chmaps[] = {
  58. { .channels = 2,
  59. .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
  60. { }
  61. };
  62. /* Channel maps for multi-channel playbacks, up to 8 n_ch */
  63. static const struct snd_pcm_chmap_elem hdmi_codec_8ch_chmaps[] = {
  64. { .channels = 2, /* CA_ID 0x00 */
  65. .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
  66. { .channels = 4, /* CA_ID 0x01 */
  67. .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
  68. SNDRV_CHMAP_NA } },
  69. { .channels = 4, /* CA_ID 0x02 */
  70. .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
  71. SNDRV_CHMAP_FC } },
  72. { .channels = 4, /* CA_ID 0x03 */
  73. .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
  74. SNDRV_CHMAP_FC } },
  75. { .channels = 6, /* CA_ID 0x04 */
  76. .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
  77. SNDRV_CHMAP_NA, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
  78. { .channels = 6, /* CA_ID 0x05 */
  79. .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
  80. SNDRV_CHMAP_NA, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
  81. { .channels = 6, /* CA_ID 0x06 */
  82. .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
  83. SNDRV_CHMAP_FC, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
  84. { .channels = 6, /* CA_ID 0x07 */
  85. .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
  86. SNDRV_CHMAP_FC, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
  87. { .channels = 6, /* CA_ID 0x08 */
  88. .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
  89. SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
  90. { .channels = 6, /* CA_ID 0x09 */
  91. .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
  92. SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
  93. { .channels = 6, /* CA_ID 0x0A */
  94. .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
  95. SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
  96. { .channels = 6, /* CA_ID 0x0B */
  97. .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
  98. SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
  99. { .channels = 8, /* CA_ID 0x0C */
  100. .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
  101. SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
  102. SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
  103. { .channels = 8, /* CA_ID 0x0D */
  104. .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
  105. SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
  106. SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
  107. { .channels = 8, /* CA_ID 0x0E */
  108. .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
  109. SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
  110. SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
  111. { .channels = 8, /* CA_ID 0x0F */
  112. .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
  113. SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
  114. SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
  115. { .channels = 8, /* CA_ID 0x10 */
  116. .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
  117. SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
  118. SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } },
  119. { .channels = 8, /* CA_ID 0x11 */
  120. .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
  121. SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
  122. SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } },
  123. { .channels = 8, /* CA_ID 0x12 */
  124. .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
  125. SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
  126. SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } },
  127. { .channels = 8, /* CA_ID 0x13 */
  128. .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
  129. SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
  130. SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } },
  131. { .channels = 8, /* CA_ID 0x14 */
  132. .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
  133. SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
  134. SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
  135. { .channels = 8, /* CA_ID 0x15 */
  136. .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
  137. SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
  138. SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
  139. { .channels = 8, /* CA_ID 0x16 */
  140. .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
  141. SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
  142. SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
  143. { .channels = 8, /* CA_ID 0x17 */
  144. .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
  145. SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
  146. SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
  147. { .channels = 8, /* CA_ID 0x18 */
  148. .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
  149. SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
  150. SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
  151. { .channels = 8, /* CA_ID 0x19 */
  152. .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
  153. SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
  154. SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
  155. { .channels = 8, /* CA_ID 0x1A */
  156. .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
  157. SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
  158. SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
  159. { .channels = 8, /* CA_ID 0x1B */
  160. .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
  161. SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
  162. SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
  163. { .channels = 8, /* CA_ID 0x1C */
  164. .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
  165. SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
  166. SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
  167. { .channels = 8, /* CA_ID 0x1D */
  168. .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
  169. SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
  170. SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
  171. { .channels = 8, /* CA_ID 0x1E */
  172. .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
  173. SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
  174. SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
  175. { .channels = 8, /* CA_ID 0x1F */
  176. .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
  177. SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
  178. SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
  179. { }
  180. };
  181. /*
  182. * hdmi_codec_channel_alloc: speaker configuration available for CEA
  183. *
  184. * This is an ordered list that must match with hdmi_codec_8ch_chmaps struct
  185. * The preceding ones have better chances to be selected by
  186. * hdmi_codec_get_ch_alloc_table_idx().
  187. */
  188. static const struct hdmi_codec_cea_spk_alloc hdmi_codec_channel_alloc[] = {
  189. { .ca_id = 0x00, .n_ch = 2,
  190. .mask = FL | FR},
  191. /* 2.1 */
  192. { .ca_id = 0x01, .n_ch = 4,
  193. .mask = FL | FR | LFE},
  194. /* Dolby Surround */
  195. { .ca_id = 0x02, .n_ch = 4,
  196. .mask = FL | FR | FC },
  197. /* surround51 */
  198. { .ca_id = 0x0b, .n_ch = 6,
  199. .mask = FL | FR | LFE | FC | RL | RR},
  200. /* surround40 */
  201. { .ca_id = 0x08, .n_ch = 6,
  202. .mask = FL | FR | RL | RR },
  203. /* surround41 */
  204. { .ca_id = 0x09, .n_ch = 6,
  205. .mask = FL | FR | LFE | RL | RR },
  206. /* surround50 */
  207. { .ca_id = 0x0a, .n_ch = 6,
  208. .mask = FL | FR | FC | RL | RR },
  209. /* 6.1 */
  210. { .ca_id = 0x0f, .n_ch = 8,
  211. .mask = FL | FR | LFE | FC | RL | RR | RC },
  212. /* surround71 */
  213. { .ca_id = 0x13, .n_ch = 8,
  214. .mask = FL | FR | LFE | FC | RL | RR | RLC | RRC },
  215. /* others */
  216. { .ca_id = 0x03, .n_ch = 8,
  217. .mask = FL | FR | LFE | FC },
  218. { .ca_id = 0x04, .n_ch = 8,
  219. .mask = FL | FR | RC},
  220. { .ca_id = 0x05, .n_ch = 8,
  221. .mask = FL | FR | LFE | RC },
  222. { .ca_id = 0x06, .n_ch = 8,
  223. .mask = FL | FR | FC | RC },
  224. { .ca_id = 0x07, .n_ch = 8,
  225. .mask = FL | FR | LFE | FC | RC },
  226. { .ca_id = 0x0c, .n_ch = 8,
  227. .mask = FL | FR | RC | RL | RR },
  228. { .ca_id = 0x0d, .n_ch = 8,
  229. .mask = FL | FR | LFE | RL | RR | RC },
  230. { .ca_id = 0x0e, .n_ch = 8,
  231. .mask = FL | FR | FC | RL | RR | RC },
  232. { .ca_id = 0x10, .n_ch = 8,
  233. .mask = FL | FR | RL | RR | RLC | RRC },
  234. { .ca_id = 0x11, .n_ch = 8,
  235. .mask = FL | FR | LFE | RL | RR | RLC | RRC },
  236. { .ca_id = 0x12, .n_ch = 8,
  237. .mask = FL | FR | FC | RL | RR | RLC | RRC },
  238. { .ca_id = 0x14, .n_ch = 8,
  239. .mask = FL | FR | FLC | FRC },
  240. { .ca_id = 0x15, .n_ch = 8,
  241. .mask = FL | FR | LFE | FLC | FRC },
  242. { .ca_id = 0x16, .n_ch = 8,
  243. .mask = FL | FR | FC | FLC | FRC },
  244. { .ca_id = 0x17, .n_ch = 8,
  245. .mask = FL | FR | LFE | FC | FLC | FRC },
  246. { .ca_id = 0x18, .n_ch = 8,
  247. .mask = FL | FR | RC | FLC | FRC },
  248. { .ca_id = 0x19, .n_ch = 8,
  249. .mask = FL | FR | LFE | RC | FLC | FRC },
  250. { .ca_id = 0x1a, .n_ch = 8,
  251. .mask = FL | FR | RC | FC | FLC | FRC },
  252. { .ca_id = 0x1b, .n_ch = 8,
  253. .mask = FL | FR | LFE | RC | FC | FLC | FRC },
  254. { .ca_id = 0x1c, .n_ch = 8,
  255. .mask = FL | FR | RL | RR | FLC | FRC },
  256. { .ca_id = 0x1d, .n_ch = 8,
  257. .mask = FL | FR | LFE | RL | RR | FLC | FRC },
  258. { .ca_id = 0x1e, .n_ch = 8,
  259. .mask = FL | FR | FC | RL | RR | FLC | FRC },
  260. { .ca_id = 0x1f, .n_ch = 8,
  261. .mask = FL | FR | LFE | FC | RL | RR | FLC | FRC },
  262. };
  263. struct hdmi_codec_priv {
  264. struct hdmi_codec_pdata hcd;
  265. uint8_t eld[MAX_ELD_BYTES];
  266. struct snd_pcm_chmap *chmap_info;
  267. unsigned int chmap_idx;
  268. struct mutex lock;
  269. bool busy;
  270. struct snd_soc_jack *jack;
  271. unsigned int jack_status;
  272. };
  273. static const struct snd_soc_dapm_widget hdmi_widgets[] = {
  274. SND_SOC_DAPM_OUTPUT("TX"),
  275. };
  276. enum {
  277. DAI_ID_I2S = 0,
  278. DAI_ID_SPDIF,
  279. };
  280. static int hdmi_eld_ctl_info(struct snd_kcontrol *kcontrol,
  281. struct snd_ctl_elem_info *uinfo)
  282. {
  283. uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
  284. uinfo->count = sizeof_field(struct hdmi_codec_priv, eld);
  285. return 0;
  286. }
  287. static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol,
  288. struct snd_ctl_elem_value *ucontrol)
  289. {
  290. struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
  291. struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
  292. memcpy(ucontrol->value.bytes.data, hcp->eld, sizeof(hcp->eld));
  293. return 0;
  294. }
  295. static unsigned long hdmi_codec_spk_mask_from_alloc(int spk_alloc)
  296. {
  297. int i;
  298. static const unsigned long hdmi_codec_eld_spk_alloc_bits[] = {
  299. [0] = FL | FR, [1] = LFE, [2] = FC, [3] = RL | RR,
  300. [4] = RC, [5] = FLC | FRC, [6] = RLC | RRC,
  301. };
  302. unsigned long spk_mask = 0;
  303. for (i = 0; i < ARRAY_SIZE(hdmi_codec_eld_spk_alloc_bits); i++) {
  304. if (spk_alloc & (1 << i))
  305. spk_mask |= hdmi_codec_eld_spk_alloc_bits[i];
  306. }
  307. return spk_mask;
  308. }
  309. static void hdmi_codec_eld_chmap(struct hdmi_codec_priv *hcp)
  310. {
  311. u8 spk_alloc;
  312. unsigned long spk_mask;
  313. spk_alloc = drm_eld_get_spk_alloc(hcp->eld);
  314. spk_mask = hdmi_codec_spk_mask_from_alloc(spk_alloc);
  315. /* Detect if only stereo supported, else return 8 channels mappings */
  316. if ((spk_mask & ~(FL | FR)) && hcp->chmap_info->max_channels > 2)
  317. hcp->chmap_info->chmap = hdmi_codec_8ch_chmaps;
  318. else
  319. hcp->chmap_info->chmap = hdmi_codec_stereo_chmaps;
  320. }
  321. static int hdmi_codec_get_ch_alloc_table_idx(struct hdmi_codec_priv *hcp,
  322. unsigned char channels)
  323. {
  324. int i;
  325. u8 spk_alloc;
  326. unsigned long spk_mask;
  327. const struct hdmi_codec_cea_spk_alloc *cap = hdmi_codec_channel_alloc;
  328. spk_alloc = drm_eld_get_spk_alloc(hcp->eld);
  329. spk_mask = hdmi_codec_spk_mask_from_alloc(spk_alloc);
  330. for (i = 0; i < ARRAY_SIZE(hdmi_codec_channel_alloc); i++, cap++) {
  331. /* If spk_alloc == 0, HDMI is unplugged return stereo config*/
  332. if (!spk_alloc && cap->ca_id == 0)
  333. return i;
  334. if (cap->n_ch != channels)
  335. continue;
  336. if (!(cap->mask == (spk_mask & cap->mask)))
  337. continue;
  338. return i;
  339. }
  340. return -EINVAL;
  341. }
  342. static int hdmi_codec_chmap_ctl_get(struct snd_kcontrol *kcontrol,
  343. struct snd_ctl_elem_value *ucontrol)
  344. {
  345. unsigned const char *map;
  346. unsigned int i;
  347. struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
  348. struct hdmi_codec_priv *hcp = info->private_data;
  349. map = info->chmap[hcp->chmap_idx].map;
  350. for (i = 0; i < info->max_channels; i++) {
  351. if (hcp->chmap_idx == HDMI_CODEC_CHMAP_IDX_UNKNOWN)
  352. ucontrol->value.integer.value[i] = 0;
  353. else
  354. ucontrol->value.integer.value[i] = map[i];
  355. }
  356. return 0;
  357. }
  358. static int hdmi_codec_startup(struct snd_pcm_substream *substream,
  359. struct snd_soc_dai *dai)
  360. {
  361. struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
  362. int ret = 0;
  363. mutex_lock(&hcp->lock);
  364. if (hcp->busy) {
  365. dev_err(dai->dev, "Only one simultaneous stream supported!\n");
  366. mutex_unlock(&hcp->lock);
  367. return -EINVAL;
  368. }
  369. if (hcp->hcd.ops->audio_startup) {
  370. ret = hcp->hcd.ops->audio_startup(dai->dev->parent, hcp->hcd.data);
  371. if (ret)
  372. goto err;
  373. }
  374. if (hcp->hcd.ops->get_eld) {
  375. ret = hcp->hcd.ops->get_eld(dai->dev->parent, hcp->hcd.data,
  376. hcp->eld, sizeof(hcp->eld));
  377. if (ret)
  378. goto err;
  379. ret = snd_pcm_hw_constraint_eld(substream->runtime, hcp->eld);
  380. if (ret)
  381. goto err;
  382. /* Select chmap supported */
  383. hdmi_codec_eld_chmap(hcp);
  384. }
  385. hcp->busy = true;
  386. err:
  387. mutex_unlock(&hcp->lock);
  388. return ret;
  389. }
  390. static void hdmi_codec_shutdown(struct snd_pcm_substream *substream,
  391. struct snd_soc_dai *dai)
  392. {
  393. struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
  394. hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN;
  395. hcp->hcd.ops->audio_shutdown(dai->dev->parent, hcp->hcd.data);
  396. mutex_lock(&hcp->lock);
  397. hcp->busy = false;
  398. mutex_unlock(&hcp->lock);
  399. }
  400. static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
  401. struct snd_pcm_hw_params *params,
  402. struct snd_soc_dai *dai)
  403. {
  404. struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
  405. struct hdmi_codec_daifmt *cf = dai->playback_dma_data;
  406. struct hdmi_codec_params hp = {
  407. .iec = {
  408. .status = { 0 },
  409. .subcode = { 0 },
  410. .pad = 0,
  411. .dig_subframe = { 0 },
  412. }
  413. };
  414. int ret, idx;
  415. dev_dbg(dai->dev, "%s() width %d rate %d channels %d\n", __func__,
  416. params_width(params), params_rate(params),
  417. params_channels(params));
  418. ret = snd_pcm_create_iec958_consumer_hw_params(params, hp.iec.status,
  419. sizeof(hp.iec.status));
  420. if (ret < 0) {
  421. dev_err(dai->dev, "Creating IEC958 channel status failed %d\n",
  422. ret);
  423. return ret;
  424. }
  425. hdmi_audio_infoframe_init(&hp.cea);
  426. hp.cea.channels = params_channels(params);
  427. hp.cea.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM;
  428. hp.cea.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM;
  429. hp.cea.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM;
  430. /* Select a channel allocation that matches with ELD and pcm channels */
  431. idx = hdmi_codec_get_ch_alloc_table_idx(hcp, hp.cea.channels);
  432. if (idx < 0) {
  433. dev_err(dai->dev, "Not able to map channels to speakers (%d)\n",
  434. idx);
  435. hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN;
  436. return idx;
  437. }
  438. hp.cea.channel_allocation = hdmi_codec_channel_alloc[idx].ca_id;
  439. hcp->chmap_idx = hdmi_codec_channel_alloc[idx].ca_id;
  440. hp.sample_width = params_width(params);
  441. hp.sample_rate = params_rate(params);
  442. hp.channels = params_channels(params);
  443. return hcp->hcd.ops->hw_params(dai->dev->parent, hcp->hcd.data,
  444. cf, &hp);
  445. }
  446. static int hdmi_codec_i2s_set_fmt(struct snd_soc_dai *dai,
  447. unsigned int fmt)
  448. {
  449. struct hdmi_codec_daifmt *cf = dai->playback_dma_data;
  450. /* Reset daifmt */
  451. memset(cf, 0, sizeof(*cf));
  452. switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
  453. case SND_SOC_DAIFMT_CBM_CFM:
  454. cf->bit_clk_master = 1;
  455. cf->frame_clk_master = 1;
  456. break;
  457. case SND_SOC_DAIFMT_CBS_CFM:
  458. cf->frame_clk_master = 1;
  459. break;
  460. case SND_SOC_DAIFMT_CBM_CFS:
  461. cf->bit_clk_master = 1;
  462. break;
  463. case SND_SOC_DAIFMT_CBS_CFS:
  464. break;
  465. default:
  466. return -EINVAL;
  467. }
  468. switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
  469. case SND_SOC_DAIFMT_NB_NF:
  470. break;
  471. case SND_SOC_DAIFMT_NB_IF:
  472. cf->frame_clk_inv = 1;
  473. break;
  474. case SND_SOC_DAIFMT_IB_NF:
  475. cf->bit_clk_inv = 1;
  476. break;
  477. case SND_SOC_DAIFMT_IB_IF:
  478. cf->frame_clk_inv = 1;
  479. cf->bit_clk_inv = 1;
  480. break;
  481. }
  482. switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
  483. case SND_SOC_DAIFMT_I2S:
  484. cf->fmt = HDMI_I2S;
  485. break;
  486. case SND_SOC_DAIFMT_DSP_A:
  487. cf->fmt = HDMI_DSP_A;
  488. break;
  489. case SND_SOC_DAIFMT_DSP_B:
  490. cf->fmt = HDMI_DSP_B;
  491. break;
  492. case SND_SOC_DAIFMT_RIGHT_J:
  493. cf->fmt = HDMI_RIGHT_J;
  494. break;
  495. case SND_SOC_DAIFMT_LEFT_J:
  496. cf->fmt = HDMI_LEFT_J;
  497. break;
  498. case SND_SOC_DAIFMT_AC97:
  499. cf->fmt = HDMI_AC97;
  500. break;
  501. default:
  502. dev_err(dai->dev, "Invalid DAI interface format\n");
  503. return -EINVAL;
  504. }
  505. return 0;
  506. }
  507. static int hdmi_codec_mute(struct snd_soc_dai *dai, int mute, int direction)
  508. {
  509. struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
  510. /*
  511. * ignore if direction was CAPTURE
  512. * and it had .no_capture_mute flag
  513. * see
  514. * snd_soc_dai_digital_mute()
  515. */
  516. if (hcp->hcd.ops->mute_stream &&
  517. (direction == SNDRV_PCM_STREAM_PLAYBACK ||
  518. !hcp->hcd.ops->no_capture_mute))
  519. return hcp->hcd.ops->mute_stream(dai->dev->parent,
  520. hcp->hcd.data,
  521. mute, direction);
  522. return -ENOTSUPP;
  523. }
  524. static const struct snd_soc_dai_ops hdmi_codec_i2s_dai_ops = {
  525. .startup = hdmi_codec_startup,
  526. .shutdown = hdmi_codec_shutdown,
  527. .hw_params = hdmi_codec_hw_params,
  528. .set_fmt = hdmi_codec_i2s_set_fmt,
  529. .mute_stream = hdmi_codec_mute,
  530. };
  531. static const struct snd_soc_dai_ops hdmi_codec_spdif_dai_ops = {
  532. .startup = hdmi_codec_startup,
  533. .shutdown = hdmi_codec_shutdown,
  534. .hw_params = hdmi_codec_hw_params,
  535. .mute_stream = hdmi_codec_mute,
  536. };
  537. #define HDMI_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
  538. SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
  539. SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |\
  540. SNDRV_PCM_RATE_192000)
  541. #define SPDIF_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |\
  542. SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE |\
  543. SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |\
  544. SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE)
  545. /*
  546. * This list is only for formats allowed on the I2S bus. So there is
  547. * some formats listed that are not supported by HDMI interface. For
  548. * instance allowing the 32-bit formats enables 24-precision with CPU
  549. * DAIs that do not support 24-bit formats. If the extra formats cause
  550. * problems, we should add the video side driver an option to disable
  551. * them.
  552. */
  553. #define I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |\
  554. SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE |\
  555. SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |\
  556. SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE |\
  557. SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE)
  558. static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd,
  559. struct snd_soc_dai *dai)
  560. {
  561. struct snd_soc_dai_driver *drv = dai->driver;
  562. struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
  563. struct snd_kcontrol *kctl;
  564. struct snd_kcontrol_new hdmi_eld_ctl = {
  565. .access = SNDRV_CTL_ELEM_ACCESS_READ |
  566. SNDRV_CTL_ELEM_ACCESS_VOLATILE,
  567. .iface = SNDRV_CTL_ELEM_IFACE_PCM,
  568. .name = "ELD",
  569. .info = hdmi_eld_ctl_info,
  570. .get = hdmi_eld_ctl_get,
  571. .device = rtd->pcm->device,
  572. };
  573. int ret;
  574. ret = snd_pcm_add_chmap_ctls(rtd->pcm, SNDRV_PCM_STREAM_PLAYBACK,
  575. NULL, drv->playback.channels_max, 0,
  576. &hcp->chmap_info);
  577. if (ret < 0)
  578. return ret;
  579. /* override handlers */
  580. hcp->chmap_info->private_data = hcp;
  581. hcp->chmap_info->kctl->get = hdmi_codec_chmap_ctl_get;
  582. /* default chmap supported is stereo */
  583. hcp->chmap_info->chmap = hdmi_codec_stereo_chmaps;
  584. hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN;
  585. /* add ELD ctl with the device number corresponding to the PCM stream */
  586. kctl = snd_ctl_new1(&hdmi_eld_ctl, dai->component);
  587. if (!kctl)
  588. return -ENOMEM;
  589. return snd_ctl_add(rtd->card->snd_card, kctl);
  590. }
  591. static int hdmi_dai_probe(struct snd_soc_dai *dai)
  592. {
  593. struct snd_soc_dapm_context *dapm;
  594. struct hdmi_codec_daifmt *daifmt;
  595. struct snd_soc_dapm_route route = {
  596. .sink = "TX",
  597. .source = dai->driver->playback.stream_name,
  598. };
  599. int ret;
  600. dapm = snd_soc_component_get_dapm(dai->component);
  601. ret = snd_soc_dapm_add_routes(dapm, &route, 1);
  602. if (ret)
  603. return ret;
  604. daifmt = kzalloc(sizeof(*daifmt), GFP_KERNEL);
  605. if (!daifmt)
  606. return -ENOMEM;
  607. dai->playback_dma_data = daifmt;
  608. return 0;
  609. }
  610. static void hdmi_codec_jack_report(struct hdmi_codec_priv *hcp,
  611. unsigned int jack_status)
  612. {
  613. if (hcp->jack && jack_status != hcp->jack_status) {
  614. snd_soc_jack_report(hcp->jack, jack_status, SND_JACK_LINEOUT);
  615. hcp->jack_status = jack_status;
  616. }
  617. }
  618. static void plugged_cb(struct device *dev, bool plugged)
  619. {
  620. struct hdmi_codec_priv *hcp = dev_get_drvdata(dev);
  621. if (plugged)
  622. hdmi_codec_jack_report(hcp, SND_JACK_LINEOUT);
  623. else
  624. hdmi_codec_jack_report(hcp, 0);
  625. }
  626. static int hdmi_codec_set_jack(struct snd_soc_component *component,
  627. struct snd_soc_jack *jack,
  628. void *data)
  629. {
  630. struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
  631. int ret = -EOPNOTSUPP;
  632. if (hcp->hcd.ops->hook_plugged_cb) {
  633. hcp->jack = jack;
  634. ret = hcp->hcd.ops->hook_plugged_cb(component->dev->parent,
  635. hcp->hcd.data,
  636. plugged_cb,
  637. component->dev);
  638. if (ret)
  639. hcp->jack = NULL;
  640. }
  641. return ret;
  642. }
  643. static int hdmi_dai_spdif_probe(struct snd_soc_dai *dai)
  644. {
  645. struct hdmi_codec_daifmt *cf = dai->playback_dma_data;
  646. int ret;
  647. ret = hdmi_dai_probe(dai);
  648. if (ret)
  649. return ret;
  650. cf = dai->playback_dma_data;
  651. cf->fmt = HDMI_SPDIF;
  652. return 0;
  653. }
  654. static int hdmi_codec_dai_remove(struct snd_soc_dai *dai)
  655. {
  656. kfree(dai->playback_dma_data);
  657. return 0;
  658. }
  659. static const struct snd_soc_dai_driver hdmi_i2s_dai = {
  660. .name = "i2s-hifi",
  661. .id = DAI_ID_I2S,
  662. .probe = hdmi_dai_probe,
  663. .remove = hdmi_codec_dai_remove,
  664. .playback = {
  665. .stream_name = "I2S Playback",
  666. .channels_min = 2,
  667. .channels_max = 8,
  668. .rates = HDMI_RATES,
  669. .formats = I2S_FORMATS,
  670. .sig_bits = 24,
  671. },
  672. .ops = &hdmi_codec_i2s_dai_ops,
  673. .pcm_new = hdmi_codec_pcm_new,
  674. };
  675. static const struct snd_soc_dai_driver hdmi_spdif_dai = {
  676. .name = "spdif-hifi",
  677. .id = DAI_ID_SPDIF,
  678. .probe = hdmi_dai_spdif_probe,
  679. .remove = hdmi_codec_dai_remove,
  680. .playback = {
  681. .stream_name = "SPDIF Playback",
  682. .channels_min = 2,
  683. .channels_max = 2,
  684. .rates = HDMI_RATES,
  685. .formats = SPDIF_FORMATS,
  686. },
  687. .ops = &hdmi_codec_spdif_dai_ops,
  688. .pcm_new = hdmi_codec_pcm_new,
  689. };
  690. static int hdmi_of_xlate_dai_id(struct snd_soc_component *component,
  691. struct device_node *endpoint)
  692. {
  693. struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
  694. int ret = -ENOTSUPP; /* see snd_soc_get_dai_id() */
  695. if (hcp->hcd.ops->get_dai_id)
  696. ret = hcp->hcd.ops->get_dai_id(component, endpoint);
  697. return ret;
  698. }
  699. static void hdmi_remove(struct snd_soc_component *component)
  700. {
  701. struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
  702. if (hcp->hcd.ops->hook_plugged_cb)
  703. hcp->hcd.ops->hook_plugged_cb(component->dev->parent,
  704. hcp->hcd.data, NULL, NULL);
  705. }
  706. static const struct snd_soc_component_driver hdmi_driver = {
  707. .remove = hdmi_remove,
  708. .dapm_widgets = hdmi_widgets,
  709. .num_dapm_widgets = ARRAY_SIZE(hdmi_widgets),
  710. .of_xlate_dai_id = hdmi_of_xlate_dai_id,
  711. .idle_bias_on = 1,
  712. .use_pmdown_time = 1,
  713. .endianness = 1,
  714. .non_legacy_dai_naming = 1,
  715. .set_jack = hdmi_codec_set_jack,
  716. };
  717. static int hdmi_codec_probe(struct platform_device *pdev)
  718. {
  719. struct hdmi_codec_pdata *hcd = pdev->dev.platform_data;
  720. struct snd_soc_dai_driver *daidrv;
  721. struct device *dev = &pdev->dev;
  722. struct hdmi_codec_priv *hcp;
  723. int dai_count, i = 0;
  724. int ret;
  725. if (!hcd) {
  726. dev_err(dev, "%s: No platform data\n", __func__);
  727. return -EINVAL;
  728. }
  729. dai_count = hcd->i2s + hcd->spdif;
  730. if (dai_count < 1 || !hcd->ops || !hcd->ops->hw_params ||
  731. !hcd->ops->audio_shutdown) {
  732. dev_err(dev, "%s: Invalid parameters\n", __func__);
  733. return -EINVAL;
  734. }
  735. hcp = devm_kzalloc(dev, sizeof(*hcp), GFP_KERNEL);
  736. if (!hcp)
  737. return -ENOMEM;
  738. hcp->hcd = *hcd;
  739. mutex_init(&hcp->lock);
  740. daidrv = devm_kcalloc(dev, dai_count, sizeof(*daidrv), GFP_KERNEL);
  741. if (!daidrv)
  742. return -ENOMEM;
  743. if (hcd->i2s) {
  744. daidrv[i] = hdmi_i2s_dai;
  745. daidrv[i].playback.channels_max = hcd->max_i2s_channels;
  746. i++;
  747. }
  748. if (hcd->spdif)
  749. daidrv[i] = hdmi_spdif_dai;
  750. dev_set_drvdata(dev, hcp);
  751. ret = devm_snd_soc_register_component(dev, &hdmi_driver, daidrv,
  752. dai_count);
  753. if (ret) {
  754. dev_err(dev, "%s: snd_soc_register_component() failed (%d)\n",
  755. __func__, ret);
  756. return ret;
  757. }
  758. return 0;
  759. }
  760. static struct platform_driver hdmi_codec_driver = {
  761. .driver = {
  762. .name = HDMI_CODEC_DRV_NAME,
  763. },
  764. .probe = hdmi_codec_probe,
  765. };
  766. module_platform_driver(hdmi_codec_driver);
  767. MODULE_AUTHOR("Jyri Sarha <jsarha@ti.com>");
  768. MODULE_DESCRIPTION("HDMI Audio Codec Driver");
  769. MODULE_LICENSE("GPL");
  770. MODULE_ALIAS("platform:" HDMI_CODEC_DRV_NAME);