hdmi_chmap.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * HDMI Channel map support helpers
  4. */
  5. #include <linux/module.h>
  6. #include <sound/control.h>
  7. #include <sound/tlv.h>
  8. #include <sound/hda_chmap.h>
  9. /*
  10. * CEA speaker placement:
  11. *
  12. * FLH FCH FRH
  13. * FLW FL FLC FC FRC FR FRW
  14. *
  15. * LFE
  16. * TC
  17. *
  18. * RL RLC RC RRC RR
  19. *
  20. * The Left/Right Surround channel _notions_ LS/RS in SMPTE 320M corresponds to
  21. * CEA RL/RR; The SMPTE channel _assignment_ C/LFE is swapped to CEA LFE/FC.
  22. */
  23. enum cea_speaker_placement {
  24. FL = (1 << 0), /* Front Left */
  25. FC = (1 << 1), /* Front Center */
  26. FR = (1 << 2), /* Front Right */
  27. FLC = (1 << 3), /* Front Left Center */
  28. FRC = (1 << 4), /* Front Right Center */
  29. RL = (1 << 5), /* Rear Left */
  30. RC = (1 << 6), /* Rear Center */
  31. RR = (1 << 7), /* Rear Right */
  32. RLC = (1 << 8), /* Rear Left Center */
  33. RRC = (1 << 9), /* Rear Right Center */
  34. LFE = (1 << 10), /* Low Frequency Effect */
  35. FLW = (1 << 11), /* Front Left Wide */
  36. FRW = (1 << 12), /* Front Right Wide */
  37. FLH = (1 << 13), /* Front Left High */
  38. FCH = (1 << 14), /* Front Center High */
  39. FRH = (1 << 15), /* Front Right High */
  40. TC = (1 << 16), /* Top Center */
  41. };
  42. static const char * const cea_speaker_allocation_names[] = {
  43. /* 0 */ "FL/FR",
  44. /* 1 */ "LFE",
  45. /* 2 */ "FC",
  46. /* 3 */ "RL/RR",
  47. /* 4 */ "RC",
  48. /* 5 */ "FLC/FRC",
  49. /* 6 */ "RLC/RRC",
  50. /* 7 */ "FLW/FRW",
  51. /* 8 */ "FLH/FRH",
  52. /* 9 */ "TC",
  53. /* 10 */ "FCH",
  54. };
  55. /*
  56. * ELD SA bits in the CEA Speaker Allocation data block
  57. */
  58. static const int eld_speaker_allocation_bits[] = {
  59. [0] = FL | FR,
  60. [1] = LFE,
  61. [2] = FC,
  62. [3] = RL | RR,
  63. [4] = RC,
  64. [5] = FLC | FRC,
  65. [6] = RLC | RRC,
  66. /* the following are not defined in ELD yet */
  67. [7] = FLW | FRW,
  68. [8] = FLH | FRH,
  69. [9] = TC,
  70. [10] = FCH,
  71. };
  72. /*
  73. * ALSA sequence is:
  74. *
  75. * surround40 surround41 surround50 surround51 surround71
  76. * ch0 front left = = = =
  77. * ch1 front right = = = =
  78. * ch2 rear left = = = =
  79. * ch3 rear right = = = =
  80. * ch4 LFE center center center
  81. * ch5 LFE LFE
  82. * ch6 side left
  83. * ch7 side right
  84. *
  85. * surround71 = {FL, FR, RLC, RRC, FC, LFE, RL, RR}
  86. */
  87. static int hdmi_channel_mapping[0x32][8] = {
  88. /* stereo */
  89. [0x00] = { 0x00, 0x11, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
  90. /* 2.1 */
  91. [0x01] = { 0x00, 0x11, 0x22, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
  92. /* Dolby Surround */
  93. [0x02] = { 0x00, 0x11, 0x23, 0xf2, 0xf4, 0xf5, 0xf6, 0xf7 },
  94. /* surround40 */
  95. [0x08] = { 0x00, 0x11, 0x24, 0x35, 0xf3, 0xf2, 0xf6, 0xf7 },
  96. /* 4ch */
  97. [0x03] = { 0x00, 0x11, 0x23, 0x32, 0x44, 0xf5, 0xf6, 0xf7 },
  98. /* surround41 */
  99. [0x09] = { 0x00, 0x11, 0x24, 0x35, 0x42, 0xf3, 0xf6, 0xf7 },
  100. /* surround50 */
  101. [0x0a] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0xf2, 0xf6, 0xf7 },
  102. /* surround51 */
  103. [0x0b] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0x52, 0xf6, 0xf7 },
  104. /* 7.1 */
  105. [0x13] = { 0x00, 0x11, 0x26, 0x37, 0x43, 0x52, 0x64, 0x75 },
  106. };
  107. /*
  108. * This is an ordered list!
  109. *
  110. * The preceding ones have better chances to be selected by
  111. * hdmi_channel_allocation().
  112. */
  113. static struct hdac_cea_channel_speaker_allocation channel_allocations[] = {
  114. /* channel: 7 6 5 4 3 2 1 0 */
  115. { .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } },
  116. /* 2.1 */
  117. { .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL } },
  118. /* Dolby Surround */
  119. { .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL } },
  120. /* surround40 */
  121. { .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } },
  122. /* surround41 */
  123. { .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } },
  124. /* surround50 */
  125. { .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } },
  126. /* surround51 */
  127. { .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } },
  128. /* 6.1 */
  129. { .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } },
  130. /* surround71 */
  131. { .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } },
  132. { .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL } },
  133. { .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL } },
  134. { .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL } },
  135. { .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL } },
  136. { .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL } },
  137. { .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL } },
  138. { .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL } },
  139. { .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL } },
  140. { .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL } },
  141. { .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL } },
  142. { .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL } },
  143. { .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL } },
  144. { .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL } },
  145. { .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL } },
  146. { .ca_index = 0x17, .speakers = { FRC, FLC, 0, 0, FC, LFE, FR, FL } },
  147. { .ca_index = 0x18, .speakers = { FRC, FLC, 0, RC, 0, 0, FR, FL } },
  148. { .ca_index = 0x19, .speakers = { FRC, FLC, 0, RC, 0, LFE, FR, FL } },
  149. { .ca_index = 0x1a, .speakers = { FRC, FLC, 0, RC, FC, 0, FR, FL } },
  150. { .ca_index = 0x1b, .speakers = { FRC, FLC, 0, RC, FC, LFE, FR, FL } },
  151. { .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, 0, 0, FR, FL } },
  152. { .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, 0, LFE, FR, FL } },
  153. { .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, 0, FR, FL } },
  154. { .ca_index = 0x1f, .speakers = { FRC, FLC, RR, RL, FC, LFE, FR, FL } },
  155. { .ca_index = 0x20, .speakers = { 0, FCH, RR, RL, FC, 0, FR, FL } },
  156. { .ca_index = 0x21, .speakers = { 0, FCH, RR, RL, FC, LFE, FR, FL } },
  157. { .ca_index = 0x22, .speakers = { TC, 0, RR, RL, FC, 0, FR, FL } },
  158. { .ca_index = 0x23, .speakers = { TC, 0, RR, RL, FC, LFE, FR, FL } },
  159. { .ca_index = 0x24, .speakers = { FRH, FLH, RR, RL, 0, 0, FR, FL } },
  160. { .ca_index = 0x25, .speakers = { FRH, FLH, RR, RL, 0, LFE, FR, FL } },
  161. { .ca_index = 0x26, .speakers = { FRW, FLW, RR, RL, 0, 0, FR, FL } },
  162. { .ca_index = 0x27, .speakers = { FRW, FLW, RR, RL, 0, LFE, FR, FL } },
  163. { .ca_index = 0x28, .speakers = { TC, RC, RR, RL, FC, 0, FR, FL } },
  164. { .ca_index = 0x29, .speakers = { TC, RC, RR, RL, FC, LFE, FR, FL } },
  165. { .ca_index = 0x2a, .speakers = { FCH, RC, RR, RL, FC, 0, FR, FL } },
  166. { .ca_index = 0x2b, .speakers = { FCH, RC, RR, RL, FC, LFE, FR, FL } },
  167. { .ca_index = 0x2c, .speakers = { TC, FCH, RR, RL, FC, 0, FR, FL } },
  168. { .ca_index = 0x2d, .speakers = { TC, FCH, RR, RL, FC, LFE, FR, FL } },
  169. { .ca_index = 0x2e, .speakers = { FRH, FLH, RR, RL, FC, 0, FR, FL } },
  170. { .ca_index = 0x2f, .speakers = { FRH, FLH, RR, RL, FC, LFE, FR, FL } },
  171. { .ca_index = 0x30, .speakers = { FRW, FLW, RR, RL, FC, 0, FR, FL } },
  172. { .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } },
  173. };
  174. static int hdmi_pin_set_slot_channel(struct hdac_device *codec,
  175. hda_nid_t pin_nid, int asp_slot, int channel)
  176. {
  177. return snd_hdac_codec_write(codec, pin_nid, 0,
  178. AC_VERB_SET_HDMI_CHAN_SLOT,
  179. (channel << 4) | asp_slot);
  180. }
  181. static int hdmi_pin_get_slot_channel(struct hdac_device *codec,
  182. hda_nid_t pin_nid, int asp_slot)
  183. {
  184. return (snd_hdac_codec_read(codec, pin_nid, 0,
  185. AC_VERB_GET_HDMI_CHAN_SLOT,
  186. asp_slot) & 0xf0) >> 4;
  187. }
  188. static int hdmi_get_channel_count(struct hdac_device *codec, hda_nid_t cvt_nid)
  189. {
  190. return 1 + snd_hdac_codec_read(codec, cvt_nid, 0,
  191. AC_VERB_GET_CVT_CHAN_COUNT, 0);
  192. }
  193. static void hdmi_set_channel_count(struct hdac_device *codec,
  194. hda_nid_t cvt_nid, int chs)
  195. {
  196. if (chs != hdmi_get_channel_count(codec, cvt_nid))
  197. snd_hdac_codec_write(codec, cvt_nid, 0,
  198. AC_VERB_SET_CVT_CHAN_COUNT, chs - 1);
  199. }
  200. /*
  201. * Channel mapping routines
  202. */
  203. /*
  204. * Compute derived values in channel_allocations[].
  205. */
  206. static void init_channel_allocations(void)
  207. {
  208. int i, j;
  209. struct hdac_cea_channel_speaker_allocation *p;
  210. for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
  211. p = channel_allocations + i;
  212. p->channels = 0;
  213. p->spk_mask = 0;
  214. for (j = 0; j < ARRAY_SIZE(p->speakers); j++)
  215. if (p->speakers[j]) {
  216. p->channels++;
  217. p->spk_mask |= p->speakers[j];
  218. }
  219. }
  220. }
  221. static int get_channel_allocation_order(int ca)
  222. {
  223. int i;
  224. for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
  225. if (channel_allocations[i].ca_index == ca)
  226. break;
  227. }
  228. return i;
  229. }
  230. void snd_hdac_print_channel_allocation(int spk_alloc, char *buf, int buflen)
  231. {
  232. int i, j;
  233. for (i = 0, j = 0; i < ARRAY_SIZE(cea_speaker_allocation_names); i++) {
  234. if (spk_alloc & (1 << i))
  235. j += scnprintf(buf + j, buflen - j, " %s",
  236. cea_speaker_allocation_names[i]);
  237. }
  238. buf[j] = '\0'; /* necessary when j == 0 */
  239. }
  240. EXPORT_SYMBOL_GPL(snd_hdac_print_channel_allocation);
  241. /*
  242. * The transformation takes two steps:
  243. *
  244. * eld->spk_alloc => (eld_speaker_allocation_bits[]) => spk_mask
  245. * spk_mask => (channel_allocations[]) => ai->CA
  246. *
  247. * TODO: it could select the wrong CA from multiple candidates.
  248. */
  249. static int hdmi_channel_allocation_spk_alloc_blk(struct hdac_device *codec,
  250. int spk_alloc, int channels)
  251. {
  252. int i;
  253. int ca = 0;
  254. int spk_mask = 0;
  255. char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
  256. /*
  257. * CA defaults to 0 for basic stereo audio
  258. */
  259. if (channels <= 2)
  260. return 0;
  261. /*
  262. * expand ELD's speaker allocation mask
  263. *
  264. * ELD tells the speaker mask in a compact(paired) form,
  265. * expand ELD's notions to match the ones used by Audio InfoFrame.
  266. */
  267. for (i = 0; i < ARRAY_SIZE(eld_speaker_allocation_bits); i++) {
  268. if (spk_alloc & (1 << i))
  269. spk_mask |= eld_speaker_allocation_bits[i];
  270. }
  271. /* search for the first working match in the CA table */
  272. for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
  273. if (channels == channel_allocations[i].channels &&
  274. (spk_mask & channel_allocations[i].spk_mask) ==
  275. channel_allocations[i].spk_mask) {
  276. ca = channel_allocations[i].ca_index;
  277. break;
  278. }
  279. }
  280. if (!ca) {
  281. /*
  282. * if there was no match, select the regular ALSA channel
  283. * allocation with the matching number of channels
  284. */
  285. for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
  286. if (channels == channel_allocations[i].channels) {
  287. ca = channel_allocations[i].ca_index;
  288. break;
  289. }
  290. }
  291. }
  292. snd_hdac_print_channel_allocation(spk_alloc, buf, sizeof(buf));
  293. dev_dbg(&codec->dev, "HDMI: select CA 0x%x for %d-channel allocation: %s\n",
  294. ca, channels, buf);
  295. return ca;
  296. }
  297. static void hdmi_debug_channel_mapping(struct hdac_chmap *chmap,
  298. hda_nid_t pin_nid)
  299. {
  300. #ifdef CONFIG_SND_DEBUG_VERBOSE
  301. int i;
  302. int channel;
  303. for (i = 0; i < 8; i++) {
  304. channel = chmap->ops.pin_get_slot_channel(
  305. chmap->hdac, pin_nid, i);
  306. dev_dbg(&chmap->hdac->dev, "HDMI: ASP channel %d => slot %d\n",
  307. channel, i);
  308. }
  309. #endif
  310. }
  311. static void hdmi_std_setup_channel_mapping(struct hdac_chmap *chmap,
  312. hda_nid_t pin_nid,
  313. bool non_pcm,
  314. int ca)
  315. {
  316. struct hdac_cea_channel_speaker_allocation *ch_alloc;
  317. int i;
  318. int err;
  319. int order;
  320. int non_pcm_mapping[8];
  321. order = get_channel_allocation_order(ca);
  322. ch_alloc = &channel_allocations[order];
  323. if (hdmi_channel_mapping[ca][1] == 0) {
  324. int hdmi_slot = 0;
  325. /* fill actual channel mappings in ALSA channel (i) order */
  326. for (i = 0; i < ch_alloc->channels; i++) {
  327. while (!WARN_ON(hdmi_slot >= 8) &&
  328. !ch_alloc->speakers[7 - hdmi_slot])
  329. hdmi_slot++; /* skip zero slots */
  330. hdmi_channel_mapping[ca][i] = (i << 4) | hdmi_slot++;
  331. }
  332. /* fill the rest of the slots with ALSA channel 0xf */
  333. for (hdmi_slot = 0; hdmi_slot < 8; hdmi_slot++)
  334. if (!ch_alloc->speakers[7 - hdmi_slot])
  335. hdmi_channel_mapping[ca][i++] = (0xf << 4) | hdmi_slot;
  336. }
  337. if (non_pcm) {
  338. for (i = 0; i < ch_alloc->channels; i++)
  339. non_pcm_mapping[i] = (i << 4) | i;
  340. for (; i < 8; i++)
  341. non_pcm_mapping[i] = (0xf << 4) | i;
  342. }
  343. for (i = 0; i < 8; i++) {
  344. int slotsetup = non_pcm ? non_pcm_mapping[i] : hdmi_channel_mapping[ca][i];
  345. int hdmi_slot = slotsetup & 0x0f;
  346. int channel = (slotsetup & 0xf0) >> 4;
  347. err = chmap->ops.pin_set_slot_channel(chmap->hdac,
  348. pin_nid, hdmi_slot, channel);
  349. if (err) {
  350. dev_dbg(&chmap->hdac->dev, "HDMI: channel mapping failed\n");
  351. break;
  352. }
  353. }
  354. }
  355. struct channel_map_table {
  356. unsigned char map; /* ALSA API channel map position */
  357. int spk_mask; /* speaker position bit mask */
  358. };
  359. static struct channel_map_table map_tables[] = {
  360. { SNDRV_CHMAP_FL, FL },
  361. { SNDRV_CHMAP_FR, FR },
  362. { SNDRV_CHMAP_RL, RL },
  363. { SNDRV_CHMAP_RR, RR },
  364. { SNDRV_CHMAP_LFE, LFE },
  365. { SNDRV_CHMAP_FC, FC },
  366. { SNDRV_CHMAP_RLC, RLC },
  367. { SNDRV_CHMAP_RRC, RRC },
  368. { SNDRV_CHMAP_RC, RC },
  369. { SNDRV_CHMAP_FLC, FLC },
  370. { SNDRV_CHMAP_FRC, FRC },
  371. { SNDRV_CHMAP_TFL, FLH },
  372. { SNDRV_CHMAP_TFR, FRH },
  373. { SNDRV_CHMAP_FLW, FLW },
  374. { SNDRV_CHMAP_FRW, FRW },
  375. { SNDRV_CHMAP_TC, TC },
  376. { SNDRV_CHMAP_TFC, FCH },
  377. {} /* terminator */
  378. };
  379. /* from ALSA API channel position to speaker bit mask */
  380. int snd_hdac_chmap_to_spk_mask(unsigned char c)
  381. {
  382. struct channel_map_table *t = map_tables;
  383. for (; t->map; t++) {
  384. if (t->map == c)
  385. return t->spk_mask;
  386. }
  387. return 0;
  388. }
  389. EXPORT_SYMBOL_GPL(snd_hdac_chmap_to_spk_mask);
  390. /* from ALSA API channel position to CEA slot */
  391. static int to_cea_slot(int ordered_ca, unsigned char pos)
  392. {
  393. int mask = snd_hdac_chmap_to_spk_mask(pos);
  394. int i;
  395. /* Add sanity check to pass klockwork check.
  396. * This should never happen.
  397. */
  398. if (ordered_ca >= ARRAY_SIZE(channel_allocations))
  399. return -1;
  400. if (mask) {
  401. for (i = 0; i < 8; i++) {
  402. if (channel_allocations[ordered_ca].speakers[7 - i] == mask)
  403. return i;
  404. }
  405. }
  406. return -1;
  407. }
  408. /* from speaker bit mask to ALSA API channel position */
  409. int snd_hdac_spk_to_chmap(int spk)
  410. {
  411. struct channel_map_table *t = map_tables;
  412. for (; t->map; t++) {
  413. if (t->spk_mask == spk)
  414. return t->map;
  415. }
  416. return 0;
  417. }
  418. EXPORT_SYMBOL_GPL(snd_hdac_spk_to_chmap);
  419. /* from CEA slot to ALSA API channel position */
  420. static int from_cea_slot(int ordered_ca, unsigned char slot)
  421. {
  422. int mask;
  423. /* Add sanity check to pass klockwork check.
  424. * This should never happen.
  425. */
  426. if (slot >= 8)
  427. return 0;
  428. mask = channel_allocations[ordered_ca].speakers[7 - slot];
  429. return snd_hdac_spk_to_chmap(mask);
  430. }
  431. /* get the CA index corresponding to the given ALSA API channel map */
  432. static int hdmi_manual_channel_allocation(int chs, unsigned char *map)
  433. {
  434. int i, spks = 0, spk_mask = 0;
  435. for (i = 0; i < chs; i++) {
  436. int mask = snd_hdac_chmap_to_spk_mask(map[i]);
  437. if (mask) {
  438. spk_mask |= mask;
  439. spks++;
  440. }
  441. }
  442. for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
  443. if ((chs == channel_allocations[i].channels ||
  444. spks == channel_allocations[i].channels) &&
  445. (spk_mask & channel_allocations[i].spk_mask) ==
  446. channel_allocations[i].spk_mask)
  447. return channel_allocations[i].ca_index;
  448. }
  449. return -1;
  450. }
  451. /* set up the channel slots for the given ALSA API channel map */
  452. static int hdmi_manual_setup_channel_mapping(struct hdac_chmap *chmap,
  453. hda_nid_t pin_nid,
  454. int chs, unsigned char *map,
  455. int ca)
  456. {
  457. int ordered_ca = get_channel_allocation_order(ca);
  458. int alsa_pos, hdmi_slot;
  459. int assignments[8] = {[0 ... 7] = 0xf};
  460. for (alsa_pos = 0; alsa_pos < chs; alsa_pos++) {
  461. hdmi_slot = to_cea_slot(ordered_ca, map[alsa_pos]);
  462. if (hdmi_slot < 0)
  463. continue; /* unassigned channel */
  464. assignments[hdmi_slot] = alsa_pos;
  465. }
  466. for (hdmi_slot = 0; hdmi_slot < 8; hdmi_slot++) {
  467. int err;
  468. err = chmap->ops.pin_set_slot_channel(chmap->hdac,
  469. pin_nid, hdmi_slot, assignments[hdmi_slot]);
  470. if (err)
  471. return -EINVAL;
  472. }
  473. return 0;
  474. }
  475. /* store ALSA API channel map from the current default map */
  476. static void hdmi_setup_fake_chmap(unsigned char *map, int ca)
  477. {
  478. int i;
  479. int ordered_ca = get_channel_allocation_order(ca);
  480. for (i = 0; i < 8; i++) {
  481. if (ordered_ca < ARRAY_SIZE(channel_allocations) &&
  482. i < channel_allocations[ordered_ca].channels)
  483. map[i] = from_cea_slot(ordered_ca, hdmi_channel_mapping[ca][i] & 0x0f);
  484. else
  485. map[i] = 0;
  486. }
  487. }
  488. void snd_hdac_setup_channel_mapping(struct hdac_chmap *chmap,
  489. hda_nid_t pin_nid, bool non_pcm, int ca,
  490. int channels, unsigned char *map,
  491. bool chmap_set)
  492. {
  493. if (!non_pcm && chmap_set) {
  494. hdmi_manual_setup_channel_mapping(chmap, pin_nid,
  495. channels, map, ca);
  496. } else {
  497. hdmi_std_setup_channel_mapping(chmap, pin_nid, non_pcm, ca);
  498. hdmi_setup_fake_chmap(map, ca);
  499. }
  500. hdmi_debug_channel_mapping(chmap, pin_nid);
  501. }
  502. EXPORT_SYMBOL_GPL(snd_hdac_setup_channel_mapping);
  503. int snd_hdac_get_active_channels(int ca)
  504. {
  505. int ordered_ca = get_channel_allocation_order(ca);
  506. /* Add sanity check to pass klockwork check.
  507. * This should never happen.
  508. */
  509. if (ordered_ca >= ARRAY_SIZE(channel_allocations))
  510. ordered_ca = 0;
  511. return channel_allocations[ordered_ca].channels;
  512. }
  513. EXPORT_SYMBOL_GPL(snd_hdac_get_active_channels);
  514. struct hdac_cea_channel_speaker_allocation *snd_hdac_get_ch_alloc_from_ca(int ca)
  515. {
  516. return &channel_allocations[get_channel_allocation_order(ca)];
  517. }
  518. EXPORT_SYMBOL_GPL(snd_hdac_get_ch_alloc_from_ca);
  519. int snd_hdac_channel_allocation(struct hdac_device *hdac, int spk_alloc,
  520. int channels, bool chmap_set, bool non_pcm, unsigned char *map)
  521. {
  522. int ca;
  523. if (!non_pcm && chmap_set)
  524. ca = hdmi_manual_channel_allocation(channels, map);
  525. else
  526. ca = hdmi_channel_allocation_spk_alloc_blk(hdac,
  527. spk_alloc, channels);
  528. if (ca < 0)
  529. ca = 0;
  530. return ca;
  531. }
  532. EXPORT_SYMBOL_GPL(snd_hdac_channel_allocation);
  533. /*
  534. * ALSA API channel-map control callbacks
  535. */
  536. static int hdmi_chmap_ctl_info(struct snd_kcontrol *kcontrol,
  537. struct snd_ctl_elem_info *uinfo)
  538. {
  539. struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
  540. struct hdac_chmap *chmap = info->private_data;
  541. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  542. uinfo->count = chmap->channels_max;
  543. uinfo->value.integer.min = 0;
  544. uinfo->value.integer.max = SNDRV_CHMAP_LAST;
  545. return 0;
  546. }
  547. static int hdmi_chmap_cea_alloc_validate_get_type(struct hdac_chmap *chmap,
  548. struct hdac_cea_channel_speaker_allocation *cap, int channels)
  549. {
  550. /* If the speaker allocation matches the channel count, it is OK.*/
  551. if (cap->channels != channels)
  552. return -1;
  553. /* all channels are remappable freely */
  554. return SNDRV_CTL_TLVT_CHMAP_VAR;
  555. }
  556. static void hdmi_cea_alloc_to_tlv_chmap(struct hdac_chmap *hchmap,
  557. struct hdac_cea_channel_speaker_allocation *cap,
  558. unsigned int *chmap, int channels)
  559. {
  560. int count = 0;
  561. int c;
  562. for (c = 7; c >= 0; c--) {
  563. int spk = cap->speakers[c];
  564. if (!spk)
  565. continue;
  566. chmap[count++] = snd_hdac_spk_to_chmap(spk);
  567. }
  568. WARN_ON(count != channels);
  569. }
  570. static int spk_mask_from_spk_alloc(int spk_alloc)
  571. {
  572. int i;
  573. int spk_mask = eld_speaker_allocation_bits[0];
  574. for (i = 0; i < ARRAY_SIZE(eld_speaker_allocation_bits); i++) {
  575. if (spk_alloc & (1 << i))
  576. spk_mask |= eld_speaker_allocation_bits[i];
  577. }
  578. return spk_mask;
  579. }
  580. static int hdmi_chmap_ctl_tlv(struct snd_kcontrol *kcontrol, int op_flag,
  581. unsigned int size, unsigned int __user *tlv)
  582. {
  583. struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
  584. struct hdac_chmap *chmap = info->private_data;
  585. int pcm_idx = kcontrol->private_value;
  586. unsigned int __user *dst;
  587. int chs, count = 0;
  588. unsigned long max_chs;
  589. int type;
  590. int spk_alloc, spk_mask;
  591. if (size < 8)
  592. return -ENOMEM;
  593. if (put_user(SNDRV_CTL_TLVT_CONTAINER, tlv))
  594. return -EFAULT;
  595. size -= 8;
  596. dst = tlv + 2;
  597. spk_alloc = chmap->ops.get_spk_alloc(chmap->hdac, pcm_idx);
  598. spk_mask = spk_mask_from_spk_alloc(spk_alloc);
  599. max_chs = hweight_long(spk_mask);
  600. for (chs = 2; chs <= max_chs; chs++) {
  601. int i;
  602. struct hdac_cea_channel_speaker_allocation *cap;
  603. cap = channel_allocations;
  604. for (i = 0; i < ARRAY_SIZE(channel_allocations); i++, cap++) {
  605. int chs_bytes = chs * 4;
  606. unsigned int tlv_chmap[8];
  607. if (cap->channels != chs)
  608. continue;
  609. if (!(cap->spk_mask == (spk_mask & cap->spk_mask)))
  610. continue;
  611. type = chmap->ops.chmap_cea_alloc_validate_get_type(
  612. chmap, cap, chs);
  613. if (type < 0)
  614. return -ENODEV;
  615. if (size < 8)
  616. return -ENOMEM;
  617. if (put_user(type, dst) ||
  618. put_user(chs_bytes, dst + 1))
  619. return -EFAULT;
  620. dst += 2;
  621. size -= 8;
  622. count += 8;
  623. if (size < chs_bytes)
  624. return -ENOMEM;
  625. size -= chs_bytes;
  626. count += chs_bytes;
  627. chmap->ops.cea_alloc_to_tlv_chmap(chmap, cap,
  628. tlv_chmap, chs);
  629. if (copy_to_user(dst, tlv_chmap, chs_bytes))
  630. return -EFAULT;
  631. dst += chs;
  632. }
  633. }
  634. if (put_user(count, tlv + 1))
  635. return -EFAULT;
  636. return 0;
  637. }
  638. static int hdmi_chmap_ctl_get(struct snd_kcontrol *kcontrol,
  639. struct snd_ctl_elem_value *ucontrol)
  640. {
  641. struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
  642. struct hdac_chmap *chmap = info->private_data;
  643. int pcm_idx = kcontrol->private_value;
  644. unsigned char pcm_chmap[8];
  645. int i;
  646. memset(pcm_chmap, 0, sizeof(pcm_chmap));
  647. chmap->ops.get_chmap(chmap->hdac, pcm_idx, pcm_chmap);
  648. for (i = 0; i < ARRAY_SIZE(pcm_chmap); i++)
  649. ucontrol->value.integer.value[i] = pcm_chmap[i];
  650. return 0;
  651. }
  652. static int hdmi_chmap_ctl_put(struct snd_kcontrol *kcontrol,
  653. struct snd_ctl_elem_value *ucontrol)
  654. {
  655. struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
  656. struct hdac_chmap *hchmap = info->private_data;
  657. int pcm_idx = kcontrol->private_value;
  658. unsigned int ctl_idx;
  659. struct snd_pcm_substream *substream;
  660. unsigned char chmap[8], per_pin_chmap[8];
  661. int i, err, ca, prepared = 0;
  662. /* No monitor is connected in dyn_pcm_assign.
  663. * It's invalid to setup the chmap
  664. */
  665. if (!hchmap->ops.is_pcm_attached(hchmap->hdac, pcm_idx))
  666. return 0;
  667. ctl_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
  668. substream = snd_pcm_chmap_substream(info, ctl_idx);
  669. if (!substream || !substream->runtime)
  670. return 0; /* just for avoiding error from alsactl restore */
  671. switch (substream->runtime->status->state) {
  672. case SNDRV_PCM_STATE_OPEN:
  673. case SNDRV_PCM_STATE_SETUP:
  674. break;
  675. case SNDRV_PCM_STATE_PREPARED:
  676. prepared = 1;
  677. break;
  678. default:
  679. return -EBUSY;
  680. }
  681. memset(chmap, 0, sizeof(chmap));
  682. for (i = 0; i < ARRAY_SIZE(chmap); i++)
  683. chmap[i] = ucontrol->value.integer.value[i];
  684. hchmap->ops.get_chmap(hchmap->hdac, pcm_idx, per_pin_chmap);
  685. if (!memcmp(chmap, per_pin_chmap, sizeof(chmap)))
  686. return 0;
  687. ca = hdmi_manual_channel_allocation(ARRAY_SIZE(chmap), chmap);
  688. if (ca < 0)
  689. return -EINVAL;
  690. if (hchmap->ops.chmap_validate) {
  691. err = hchmap->ops.chmap_validate(hchmap, ca,
  692. ARRAY_SIZE(chmap), chmap);
  693. if (err)
  694. return err;
  695. }
  696. hchmap->ops.set_chmap(hchmap->hdac, pcm_idx, chmap, prepared);
  697. return 0;
  698. }
  699. static const struct hdac_chmap_ops chmap_ops = {
  700. .chmap_cea_alloc_validate_get_type = hdmi_chmap_cea_alloc_validate_get_type,
  701. .cea_alloc_to_tlv_chmap = hdmi_cea_alloc_to_tlv_chmap,
  702. .pin_get_slot_channel = hdmi_pin_get_slot_channel,
  703. .pin_set_slot_channel = hdmi_pin_set_slot_channel,
  704. .set_channel_count = hdmi_set_channel_count,
  705. };
  706. void snd_hdac_register_chmap_ops(struct hdac_device *hdac,
  707. struct hdac_chmap *chmap)
  708. {
  709. chmap->ops = chmap_ops;
  710. chmap->hdac = hdac;
  711. init_channel_allocations();
  712. }
  713. EXPORT_SYMBOL_GPL(snd_hdac_register_chmap_ops);
  714. int snd_hdac_add_chmap_ctls(struct snd_pcm *pcm, int pcm_idx,
  715. struct hdac_chmap *hchmap)
  716. {
  717. struct snd_pcm_chmap *chmap;
  718. struct snd_kcontrol *kctl;
  719. int err, i;
  720. err = snd_pcm_add_chmap_ctls(pcm,
  721. SNDRV_PCM_STREAM_PLAYBACK,
  722. NULL, 0, pcm_idx, &chmap);
  723. if (err < 0)
  724. return err;
  725. /* override handlers */
  726. chmap->private_data = hchmap;
  727. kctl = chmap->kctl;
  728. for (i = 0; i < kctl->count; i++)
  729. kctl->vd[i].access |= SNDRV_CTL_ELEM_ACCESS_WRITE;
  730. kctl->info = hdmi_chmap_ctl_info;
  731. kctl->get = hdmi_chmap_ctl_get;
  732. kctl->put = hdmi_chmap_ctl_put;
  733. kctl->tlv.c = hdmi_chmap_ctl_tlv;
  734. return 0;
  735. }
  736. EXPORT_SYMBOL_GPL(snd_hdac_add_chmap_ctls);