hdmi_chmap.c 24 KB

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