patch_intelhdmi.c 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009
  1. /*
  2. *
  3. * patch_intelhdmi.c - Patch for Intel HDMI codecs
  4. *
  5. * Copyright(c) 2008 Intel Corporation. All rights reserved.
  6. *
  7. * Authors:
  8. * Jiang Zhe <zhe.jiang@intel.com>
  9. * Wu Fengguang <wfg@linux.intel.com>
  10. *
  11. * Maintained by:
  12. * Wu Fengguang <wfg@linux.intel.com>
  13. *
  14. * This program is free software; you can redistribute it and/or modify it
  15. * under the terms of the GNU General Public License as published by the Free
  16. * Software Foundation; either version 2 of the License, or (at your option)
  17. * any later version.
  18. *
  19. * This program is distributed in the hope that it will be useful, but
  20. * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  21. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  22. * for more details.
  23. *
  24. * You should have received a copy of the GNU General Public License
  25. * along with this program; if not, write to the Free Software Foundation,
  26. * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  27. */
  28. #include <linux/init.h>
  29. #include <linux/delay.h>
  30. #include <linux/slab.h>
  31. #include <sound/core.h>
  32. #include "hda_codec.h"
  33. #include "hda_local.h"
  34. /*
  35. * The HDMI/DisplayPort configuration can be highly dynamic. A graphics device
  36. * could support two independent pipes, each of them can be connected to one or
  37. * more ports (DVI, HDMI or DisplayPort).
  38. *
  39. * The HDA correspondence of pipes/ports are converter/pin nodes.
  40. */
  41. #define INTEL_HDMI_CVTS 2
  42. #define INTEL_HDMI_PINS 3
  43. static char *intel_hdmi_pcm_names[INTEL_HDMI_CVTS] = {
  44. "INTEL HDMI 0",
  45. "INTEL HDMI 1",
  46. };
  47. struct intel_hdmi_spec {
  48. int num_cvts;
  49. int num_pins;
  50. hda_nid_t cvt[INTEL_HDMI_CVTS+1]; /* audio sources */
  51. hda_nid_t pin[INTEL_HDMI_PINS+1]; /* audio sinks */
  52. /*
  53. * source connection for each pin
  54. */
  55. hda_nid_t pin_cvt[INTEL_HDMI_PINS+1];
  56. /*
  57. * HDMI sink attached to each pin
  58. */
  59. struct hdmi_eld sink_eld[INTEL_HDMI_PINS];
  60. /*
  61. * export one pcm per pipe
  62. */
  63. struct hda_pcm pcm_rec[INTEL_HDMI_CVTS];
  64. };
  65. struct hdmi_audio_infoframe {
  66. u8 type; /* 0x84 */
  67. u8 ver; /* 0x01 */
  68. u8 len; /* 0x0a */
  69. u8 checksum; /* PB0 */
  70. u8 CC02_CT47; /* CC in bits 0:2, CT in 4:7 */
  71. u8 SS01_SF24;
  72. u8 CXT04;
  73. u8 CA;
  74. u8 LFEPBL01_LSV36_DM_INH7;
  75. u8 reserved[5]; /* PB6 - PB10 */
  76. };
  77. /*
  78. * CEA speaker placement:
  79. *
  80. * FLH FCH FRH
  81. * FLW FL FLC FC FRC FR FRW
  82. *
  83. * LFE
  84. * TC
  85. *
  86. * RL RLC RC RRC RR
  87. *
  88. * The Left/Right Surround channel _notions_ LS/RS in SMPTE 320M corresponds to
  89. * CEA RL/RR; The SMPTE channel _assignment_ C/LFE is swapped to CEA LFE/FC.
  90. */
  91. enum cea_speaker_placement {
  92. FL = (1 << 0), /* Front Left */
  93. FC = (1 << 1), /* Front Center */
  94. FR = (1 << 2), /* Front Right */
  95. FLC = (1 << 3), /* Front Left Center */
  96. FRC = (1 << 4), /* Front Right Center */
  97. RL = (1 << 5), /* Rear Left */
  98. RC = (1 << 6), /* Rear Center */
  99. RR = (1 << 7), /* Rear Right */
  100. RLC = (1 << 8), /* Rear Left Center */
  101. RRC = (1 << 9), /* Rear Right Center */
  102. LFE = (1 << 10), /* Low Frequency Effect */
  103. FLW = (1 << 11), /* Front Left Wide */
  104. FRW = (1 << 12), /* Front Right Wide */
  105. FLH = (1 << 13), /* Front Left High */
  106. FCH = (1 << 14), /* Front Center High */
  107. FRH = (1 << 15), /* Front Right High */
  108. TC = (1 << 16), /* Top Center */
  109. };
  110. /*
  111. * ELD SA bits in the CEA Speaker Allocation data block
  112. */
  113. static int eld_speaker_allocation_bits[] = {
  114. [0] = FL | FR,
  115. [1] = LFE,
  116. [2] = FC,
  117. [3] = RL | RR,
  118. [4] = RC,
  119. [5] = FLC | FRC,
  120. [6] = RLC | RRC,
  121. /* the following are not defined in ELD yet */
  122. [7] = FLW | FRW,
  123. [8] = FLH | FRH,
  124. [9] = TC,
  125. [10] = FCH,
  126. };
  127. struct cea_channel_speaker_allocation {
  128. int ca_index;
  129. int speakers[8];
  130. /* derived values, just for convenience */
  131. int channels;
  132. int spk_mask;
  133. };
  134. /*
  135. * ALSA sequence is:
  136. *
  137. * surround40 surround41 surround50 surround51 surround71
  138. * ch0 front left = = = =
  139. * ch1 front right = = = =
  140. * ch2 rear left = = = =
  141. * ch3 rear right = = = =
  142. * ch4 LFE center center center
  143. * ch5 LFE LFE
  144. * ch6 side left
  145. * ch7 side right
  146. *
  147. * surround71 = {FL, FR, RLC, RRC, FC, LFE, RL, RR}
  148. */
  149. static int hdmi_channel_mapping[0x32][8] = {
  150. /* stereo */
  151. [0x00] = { 0x00, 0x11, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
  152. /* 2.1 */
  153. [0x01] = { 0x00, 0x11, 0x22, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
  154. /* Dolby Surround */
  155. [0x02] = { 0x00, 0x11, 0x23, 0xf2, 0xf4, 0xf5, 0xf6, 0xf7 },
  156. /* surround40 */
  157. [0x08] = { 0x00, 0x11, 0x24, 0x35, 0xf3, 0xf2, 0xf6, 0xf7 },
  158. /* 4ch */
  159. [0x03] = { 0x00, 0x11, 0x23, 0x32, 0x44, 0xf5, 0xf6, 0xf7 },
  160. /* surround41 */
  161. [0x09] = { 0x00, 0x11, 0x24, 0x34, 0x43, 0xf2, 0xf6, 0xf7 },
  162. /* surround50 */
  163. [0x0a] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0xf2, 0xf6, 0xf7 },
  164. /* surround51 */
  165. [0x0b] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0x52, 0xf6, 0xf7 },
  166. /* 7.1 */
  167. [0x13] = { 0x00, 0x11, 0x26, 0x37, 0x43, 0x52, 0x64, 0x75 },
  168. };
  169. /*
  170. * This is an ordered list!
  171. *
  172. * The preceding ones have better chances to be selected by
  173. * hdmi_setup_channel_allocation().
  174. */
  175. static struct cea_channel_speaker_allocation channel_allocations[] = {
  176. /* channel: 7 6 5 4 3 2 1 0 */
  177. { .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } },
  178. /* 2.1 */
  179. { .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL } },
  180. /* Dolby Surround */
  181. { .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL } },
  182. /* surround40 */
  183. { .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } },
  184. /* surround41 */
  185. { .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } },
  186. /* surround50 */
  187. { .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } },
  188. /* surround51 */
  189. { .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } },
  190. /* 6.1 */
  191. { .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } },
  192. /* surround71 */
  193. { .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } },
  194. { .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL } },
  195. { .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL } },
  196. { .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL } },
  197. { .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL } },
  198. { .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL } },
  199. { .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL } },
  200. { .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL } },
  201. { .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL } },
  202. { .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL } },
  203. { .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL } },
  204. { .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL } },
  205. { .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL } },
  206. { .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL } },
  207. { .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL } },
  208. { .ca_index = 0x17, .speakers = { FRC, FLC, 0, 0, FC, LFE, FR, FL } },
  209. { .ca_index = 0x18, .speakers = { FRC, FLC, 0, RC, 0, 0, FR, FL } },
  210. { .ca_index = 0x19, .speakers = { FRC, FLC, 0, RC, 0, LFE, FR, FL } },
  211. { .ca_index = 0x1a, .speakers = { FRC, FLC, 0, RC, FC, 0, FR, FL } },
  212. { .ca_index = 0x1b, .speakers = { FRC, FLC, 0, RC, FC, LFE, FR, FL } },
  213. { .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, 0, 0, FR, FL } },
  214. { .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, 0, LFE, FR, FL } },
  215. { .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, 0, FR, FL } },
  216. { .ca_index = 0x1f, .speakers = { FRC, FLC, RR, RL, FC, LFE, FR, FL } },
  217. { .ca_index = 0x20, .speakers = { 0, FCH, RR, RL, FC, 0, FR, FL } },
  218. { .ca_index = 0x21, .speakers = { 0, FCH, RR, RL, FC, LFE, FR, FL } },
  219. { .ca_index = 0x22, .speakers = { TC, 0, RR, RL, FC, 0, FR, FL } },
  220. { .ca_index = 0x23, .speakers = { TC, 0, RR, RL, FC, LFE, FR, FL } },
  221. { .ca_index = 0x24, .speakers = { FRH, FLH, RR, RL, 0, 0, FR, FL } },
  222. { .ca_index = 0x25, .speakers = { FRH, FLH, RR, RL, 0, LFE, FR, FL } },
  223. { .ca_index = 0x26, .speakers = { FRW, FLW, RR, RL, 0, 0, FR, FL } },
  224. { .ca_index = 0x27, .speakers = { FRW, FLW, RR, RL, 0, LFE, FR, FL } },
  225. { .ca_index = 0x28, .speakers = { TC, RC, RR, RL, FC, 0, FR, FL } },
  226. { .ca_index = 0x29, .speakers = { TC, RC, RR, RL, FC, LFE, FR, FL } },
  227. { .ca_index = 0x2a, .speakers = { FCH, RC, RR, RL, FC, 0, FR, FL } },
  228. { .ca_index = 0x2b, .speakers = { FCH, RC, RR, RL, FC, LFE, FR, FL } },
  229. { .ca_index = 0x2c, .speakers = { TC, FCH, RR, RL, FC, 0, FR, FL } },
  230. { .ca_index = 0x2d, .speakers = { TC, FCH, RR, RL, FC, LFE, FR, FL } },
  231. { .ca_index = 0x2e, .speakers = { FRH, FLH, RR, RL, FC, 0, FR, FL } },
  232. { .ca_index = 0x2f, .speakers = { FRH, FLH, RR, RL, FC, LFE, FR, FL } },
  233. { .ca_index = 0x30, .speakers = { FRW, FLW, RR, RL, FC, 0, FR, FL } },
  234. { .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } },
  235. };
  236. /*
  237. * HDA/HDMI auto parsing
  238. */
  239. static int hda_node_index(hda_nid_t *nids, hda_nid_t nid)
  240. {
  241. int i;
  242. for (i = 0; nids[i]; i++)
  243. if (nids[i] == nid)
  244. return i;
  245. snd_printk(KERN_WARNING "HDMI: nid %d not registered\n", nid);
  246. return -EINVAL;
  247. }
  248. static int intel_hdmi_read_pin_conn(struct hda_codec *codec, hda_nid_t pin_nid)
  249. {
  250. struct intel_hdmi_spec *spec = codec->spec;
  251. hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
  252. int conn_len, curr;
  253. int index;
  254. if (!(get_wcaps(codec, pin_nid) & AC_WCAP_CONN_LIST)) {
  255. snd_printk(KERN_WARNING
  256. "HDMI: pin %d wcaps %#x "
  257. "does not support connection list\n",
  258. pin_nid, get_wcaps(codec, pin_nid));
  259. return -EINVAL;
  260. }
  261. conn_len = snd_hda_get_connections(codec, pin_nid, conn_list,
  262. HDA_MAX_CONNECTIONS);
  263. if (conn_len > 1)
  264. curr = snd_hda_codec_read(codec, pin_nid, 0,
  265. AC_VERB_GET_CONNECT_SEL, 0);
  266. else
  267. curr = 0;
  268. index = hda_node_index(spec->pin, pin_nid);
  269. if (index < 0)
  270. return -EINVAL;
  271. spec->pin_cvt[index] = conn_list[curr];
  272. return 0;
  273. }
  274. static void hdmi_get_show_eld(struct hda_codec *codec, hda_nid_t pin_nid,
  275. struct hdmi_eld *eld)
  276. {
  277. if (!snd_hdmi_get_eld(eld, codec, pin_nid))
  278. snd_hdmi_show_eld(eld);
  279. }
  280. static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid,
  281. struct hdmi_eld *eld)
  282. {
  283. int present = snd_hda_pin_sense(codec, pin_nid);
  284. eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE);
  285. eld->eld_valid = !!(present & AC_PINSENSE_ELDV);
  286. if (present & AC_PINSENSE_ELDV)
  287. hdmi_get_show_eld(codec, pin_nid, eld);
  288. }
  289. static int intel_hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
  290. {
  291. struct intel_hdmi_spec *spec = codec->spec;
  292. if (spec->num_pins >= INTEL_HDMI_PINS) {
  293. snd_printk(KERN_WARNING
  294. "HDMI: no space for pin %d \n", pin_nid);
  295. return -EINVAL;
  296. }
  297. hdmi_present_sense(codec, pin_nid, &spec->sink_eld[spec->num_pins]);
  298. spec->pin[spec->num_pins] = pin_nid;
  299. spec->num_pins++;
  300. /*
  301. * It is assumed that converter nodes come first in the node list and
  302. * hence have been registered and usable now.
  303. */
  304. return intel_hdmi_read_pin_conn(codec, pin_nid);
  305. }
  306. static int intel_hdmi_add_cvt(struct hda_codec *codec, hda_nid_t nid)
  307. {
  308. struct intel_hdmi_spec *spec = codec->spec;
  309. if (spec->num_cvts >= INTEL_HDMI_CVTS) {
  310. snd_printk(KERN_WARNING
  311. "HDMI: no space for converter %d \n", nid);
  312. return -EINVAL;
  313. }
  314. spec->cvt[spec->num_cvts] = nid;
  315. spec->num_cvts++;
  316. return 0;
  317. }
  318. static int intel_hdmi_parse_codec(struct hda_codec *codec)
  319. {
  320. hda_nid_t nid;
  321. int i, nodes;
  322. nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid);
  323. if (!nid || nodes < 0) {
  324. snd_printk(KERN_WARNING "HDMI: failed to get afg sub nodes\n");
  325. return -EINVAL;
  326. }
  327. for (i = 0; i < nodes; i++, nid++) {
  328. unsigned int caps;
  329. unsigned int type;
  330. caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
  331. type = get_wcaps_type(caps);
  332. if (!(caps & AC_WCAP_DIGITAL))
  333. continue;
  334. switch (type) {
  335. case AC_WID_AUD_OUT:
  336. if (intel_hdmi_add_cvt(codec, nid) < 0)
  337. return -EINVAL;
  338. break;
  339. case AC_WID_PIN:
  340. caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
  341. if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP)))
  342. continue;
  343. if (intel_hdmi_add_pin(codec, nid) < 0)
  344. return -EINVAL;
  345. break;
  346. }
  347. }
  348. return 0;
  349. }
  350. /*
  351. * HDMI routines
  352. */
  353. #ifdef BE_PARANOID
  354. static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t pin_nid,
  355. int *packet_index, int *byte_index)
  356. {
  357. int val;
  358. val = snd_hda_codec_read(codec, pin_nid, 0,
  359. AC_VERB_GET_HDMI_DIP_INDEX, 0);
  360. *packet_index = val >> 5;
  361. *byte_index = val & 0x1f;
  362. }
  363. #endif
  364. static void hdmi_set_dip_index(struct hda_codec *codec, hda_nid_t pin_nid,
  365. int packet_index, int byte_index)
  366. {
  367. int val;
  368. val = (packet_index << 5) | (byte_index & 0x1f);
  369. snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_INDEX, val);
  370. }
  371. static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t pin_nid,
  372. unsigned char val)
  373. {
  374. snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_DATA, val);
  375. }
  376. static void hdmi_enable_output(struct hda_codec *codec, hda_nid_t pin_nid)
  377. {
  378. /* Unmute */
  379. if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP)
  380. snd_hda_codec_write(codec, pin_nid, 0,
  381. AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
  382. /* Enable pin out */
  383. snd_hda_codec_write(codec, pin_nid, 0,
  384. AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
  385. }
  386. /*
  387. * Enable Audio InfoFrame Transmission
  388. */
  389. static void hdmi_start_infoframe_trans(struct hda_codec *codec,
  390. hda_nid_t pin_nid)
  391. {
  392. hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
  393. snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
  394. AC_DIPXMIT_BEST);
  395. }
  396. /*
  397. * Disable Audio InfoFrame Transmission
  398. */
  399. static void hdmi_stop_infoframe_trans(struct hda_codec *codec,
  400. hda_nid_t pin_nid)
  401. {
  402. hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
  403. snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
  404. AC_DIPXMIT_DISABLE);
  405. }
  406. static int hdmi_get_channel_count(struct hda_codec *codec, hda_nid_t nid)
  407. {
  408. return 1 + snd_hda_codec_read(codec, nid, 0,
  409. AC_VERB_GET_CVT_CHAN_COUNT, 0);
  410. }
  411. static void hdmi_set_channel_count(struct hda_codec *codec,
  412. hda_nid_t nid, int chs)
  413. {
  414. if (chs != hdmi_get_channel_count(codec, nid))
  415. snd_hda_codec_write(codec, nid, 0,
  416. AC_VERB_SET_CVT_CHAN_COUNT, chs - 1);
  417. }
  418. static void hdmi_debug_channel_mapping(struct hda_codec *codec,
  419. hda_nid_t pin_nid)
  420. {
  421. #ifdef CONFIG_SND_DEBUG_VERBOSE
  422. int i;
  423. int slot;
  424. for (i = 0; i < 8; i++) {
  425. slot = snd_hda_codec_read(codec, pin_nid, 0,
  426. AC_VERB_GET_HDMI_CHAN_SLOT, i);
  427. printk(KERN_DEBUG "HDMI: ASP channel %d => slot %d\n",
  428. slot >> 4, slot & 0xf);
  429. }
  430. #endif
  431. }
  432. /*
  433. * Audio InfoFrame routines
  434. */
  435. static void hdmi_debug_dip_size(struct hda_codec *codec, hda_nid_t pin_nid)
  436. {
  437. #ifdef CONFIG_SND_DEBUG_VERBOSE
  438. int i;
  439. int size;
  440. size = snd_hdmi_get_eld_size(codec, pin_nid);
  441. printk(KERN_DEBUG "HDMI: ELD buf size is %d\n", size);
  442. for (i = 0; i < 8; i++) {
  443. size = snd_hda_codec_read(codec, pin_nid, 0,
  444. AC_VERB_GET_HDMI_DIP_SIZE, i);
  445. printk(KERN_DEBUG "HDMI: DIP GP[%d] buf size is %d\n", i, size);
  446. }
  447. #endif
  448. }
  449. static void hdmi_clear_dip_buffers(struct hda_codec *codec, hda_nid_t pin_nid)
  450. {
  451. #ifdef BE_PARANOID
  452. int i, j;
  453. int size;
  454. int pi, bi;
  455. for (i = 0; i < 8; i++) {
  456. size = snd_hda_codec_read(codec, pin_nid, 0,
  457. AC_VERB_GET_HDMI_DIP_SIZE, i);
  458. if (size == 0)
  459. continue;
  460. hdmi_set_dip_index(codec, pin_nid, i, 0x0);
  461. for (j = 1; j < 1000; j++) {
  462. hdmi_write_dip_byte(codec, pin_nid, 0x0);
  463. hdmi_get_dip_index(codec, pin_nid, &pi, &bi);
  464. if (pi != i)
  465. snd_printd(KERN_INFO "dip index %d: %d != %d\n",
  466. bi, pi, i);
  467. if (bi == 0) /* byte index wrapped around */
  468. break;
  469. }
  470. snd_printd(KERN_INFO
  471. "HDMI: DIP GP[%d] buf reported size=%d, written=%d\n",
  472. i, size, j);
  473. }
  474. #endif
  475. }
  476. static void hdmi_checksum_audio_infoframe(struct hdmi_audio_infoframe *ai)
  477. {
  478. u8 *bytes = (u8 *)ai;
  479. u8 sum = 0;
  480. int i;
  481. ai->checksum = 0;
  482. for (i = 0; i < sizeof(*ai); i++)
  483. sum += bytes[i];
  484. ai->checksum = - sum;
  485. }
  486. static void hdmi_fill_audio_infoframe(struct hda_codec *codec,
  487. hda_nid_t pin_nid,
  488. struct hdmi_audio_infoframe *ai)
  489. {
  490. u8 *bytes = (u8 *)ai;
  491. int i;
  492. hdmi_debug_dip_size(codec, pin_nid);
  493. hdmi_clear_dip_buffers(codec, pin_nid); /* be paranoid */
  494. hdmi_checksum_audio_infoframe(ai);
  495. hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
  496. for (i = 0; i < sizeof(*ai); i++)
  497. hdmi_write_dip_byte(codec, pin_nid, bytes[i]);
  498. }
  499. /*
  500. * Compute derived values in channel_allocations[].
  501. */
  502. static void init_channel_allocations(void)
  503. {
  504. int i, j;
  505. struct cea_channel_speaker_allocation *p;
  506. for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
  507. p = channel_allocations + i;
  508. p->channels = 0;
  509. p->spk_mask = 0;
  510. for (j = 0; j < ARRAY_SIZE(p->speakers); j++)
  511. if (p->speakers[j]) {
  512. p->channels++;
  513. p->spk_mask |= p->speakers[j];
  514. }
  515. }
  516. }
  517. /*
  518. * The transformation takes two steps:
  519. *
  520. * eld->spk_alloc => (eld_speaker_allocation_bits[]) => spk_mask
  521. * spk_mask => (channel_allocations[]) => ai->CA
  522. *
  523. * TODO: it could select the wrong CA from multiple candidates.
  524. */
  525. static int hdmi_setup_channel_allocation(struct hda_codec *codec, hda_nid_t nid,
  526. struct hdmi_audio_infoframe *ai)
  527. {
  528. struct intel_hdmi_spec *spec = codec->spec;
  529. struct hdmi_eld *eld;
  530. int i;
  531. int spk_mask = 0;
  532. int channels = 1 + (ai->CC02_CT47 & 0x7);
  533. char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
  534. /*
  535. * CA defaults to 0 for basic stereo audio
  536. */
  537. if (channels <= 2)
  538. return 0;
  539. i = hda_node_index(spec->pin_cvt, nid);
  540. if (i < 0)
  541. return 0;
  542. eld = &spec->sink_eld[i];
  543. /*
  544. * HDMI sink's ELD info cannot always be retrieved for now, e.g.
  545. * in console or for audio devices. Assume the highest speakers
  546. * configuration, to _not_ prohibit multi-channel audio playback.
  547. */
  548. if (!eld->spk_alloc)
  549. eld->spk_alloc = 0xffff;
  550. /*
  551. * expand ELD's speaker allocation mask
  552. *
  553. * ELD tells the speaker mask in a compact(paired) form,
  554. * expand ELD's notions to match the ones used by Audio InfoFrame.
  555. */
  556. for (i = 0; i < ARRAY_SIZE(eld_speaker_allocation_bits); i++) {
  557. if (eld->spk_alloc & (1 << i))
  558. spk_mask |= eld_speaker_allocation_bits[i];
  559. }
  560. /* search for the first working match in the CA table */
  561. for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
  562. if (channels == channel_allocations[i].channels &&
  563. (spk_mask & channel_allocations[i].spk_mask) ==
  564. channel_allocations[i].spk_mask) {
  565. ai->CA = channel_allocations[i].ca_index;
  566. break;
  567. }
  568. }
  569. snd_print_channel_allocation(eld->spk_alloc, buf, sizeof(buf));
  570. snd_printdd(KERN_INFO
  571. "HDMI: select CA 0x%x for %d-channel allocation: %s\n",
  572. ai->CA, channels, buf);
  573. return ai->CA;
  574. }
  575. static void hdmi_setup_channel_mapping(struct hda_codec *codec,
  576. hda_nid_t pin_nid,
  577. struct hdmi_audio_infoframe *ai)
  578. {
  579. int i;
  580. int ca = ai->CA;
  581. int err;
  582. if (hdmi_channel_mapping[ca][1] == 0) {
  583. for (i = 0; i < channel_allocations[ca].channels; i++)
  584. hdmi_channel_mapping[ca][i] = i | (i << 4);
  585. for (; i < 8; i++)
  586. hdmi_channel_mapping[ca][i] = 0xf | (i << 4);
  587. }
  588. for (i = 0; i < 8; i++) {
  589. err = snd_hda_codec_write(codec, pin_nid, 0,
  590. AC_VERB_SET_HDMI_CHAN_SLOT,
  591. hdmi_channel_mapping[ca][i]);
  592. if (err) {
  593. snd_printdd(KERN_INFO "HDMI: channel mapping failed\n");
  594. break;
  595. }
  596. }
  597. hdmi_debug_channel_mapping(codec, pin_nid);
  598. }
  599. static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid,
  600. struct hdmi_audio_infoframe *ai)
  601. {
  602. u8 *bytes = (u8 *)ai;
  603. u8 val;
  604. int i;
  605. if (snd_hda_codec_read(codec, pin_nid, 0, AC_VERB_GET_HDMI_DIP_XMIT, 0)
  606. != AC_DIPXMIT_BEST)
  607. return false;
  608. hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
  609. for (i = 0; i < sizeof(*ai); i++) {
  610. val = snd_hda_codec_read(codec, pin_nid, 0,
  611. AC_VERB_GET_HDMI_DIP_DATA, 0);
  612. if (val != bytes[i])
  613. return false;
  614. }
  615. return true;
  616. }
  617. static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid,
  618. struct snd_pcm_substream *substream)
  619. {
  620. struct intel_hdmi_spec *spec = codec->spec;
  621. hda_nid_t pin_nid;
  622. int i;
  623. struct hdmi_audio_infoframe ai = {
  624. .type = 0x84,
  625. .ver = 0x01,
  626. .len = 0x0a,
  627. .CC02_CT47 = substream->runtime->channels - 1,
  628. };
  629. hdmi_setup_channel_allocation(codec, nid, &ai);
  630. for (i = 0; i < spec->num_pins; i++) {
  631. if (spec->pin_cvt[i] != nid)
  632. continue;
  633. if (!spec->sink_eld[i].monitor_present)
  634. continue;
  635. pin_nid = spec->pin[i];
  636. if (!hdmi_infoframe_uptodate(codec, pin_nid, &ai)) {
  637. hdmi_setup_channel_mapping(codec, pin_nid, &ai);
  638. hdmi_stop_infoframe_trans(codec, pin_nid);
  639. hdmi_fill_audio_infoframe(codec, pin_nid, &ai);
  640. hdmi_start_infoframe_trans(codec, pin_nid);
  641. }
  642. }
  643. }
  644. /*
  645. * Unsolicited events
  646. */
  647. static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
  648. {
  649. struct intel_hdmi_spec *spec = codec->spec;
  650. int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
  651. int pind = !!(res & AC_UNSOL_RES_PD);
  652. int eldv = !!(res & AC_UNSOL_RES_ELDV);
  653. int index;
  654. printk(KERN_INFO
  655. "HDMI hot plug event: Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
  656. tag, pind, eldv);
  657. index = hda_node_index(spec->pin, tag);
  658. if (index < 0)
  659. return;
  660. spec->sink_eld[index].monitor_present = pind;
  661. spec->sink_eld[index].eld_valid = eldv;
  662. if (pind && eldv) {
  663. hdmi_get_show_eld(codec, spec->pin[index], &spec->sink_eld[index]);
  664. /* TODO: do real things about ELD */
  665. }
  666. }
  667. static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
  668. {
  669. int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
  670. int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
  671. int cp_state = !!(res & AC_UNSOL_RES_CP_STATE);
  672. int cp_ready = !!(res & AC_UNSOL_RES_CP_READY);
  673. printk(KERN_INFO
  674. "HDMI CP event: PIN=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n",
  675. tag,
  676. subtag,
  677. cp_state,
  678. cp_ready);
  679. /* TODO */
  680. if (cp_state)
  681. ;
  682. if (cp_ready)
  683. ;
  684. }
  685. static void intel_hdmi_unsol_event(struct hda_codec *codec, unsigned int res)
  686. {
  687. struct intel_hdmi_spec *spec = codec->spec;
  688. int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
  689. int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
  690. if (hda_node_index(spec->pin, tag) < 0) {
  691. snd_printd(KERN_INFO "Unexpected HDMI event tag 0x%x\n", tag);
  692. return;
  693. }
  694. if (subtag == 0)
  695. hdmi_intrinsic_event(codec, res);
  696. else
  697. hdmi_non_intrinsic_event(codec, res);
  698. }
  699. /*
  700. * Callbacks
  701. */
  702. static void hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid,
  703. u32 stream_tag, int format)
  704. {
  705. int tag;
  706. int fmt;
  707. tag = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0) >> 4;
  708. fmt = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_STREAM_FORMAT, 0);
  709. snd_printdd("hdmi_setup_stream: "
  710. "NID=0x%x, %sstream=0x%x, %sformat=0x%x\n",
  711. nid,
  712. tag == stream_tag ? "" : "new-",
  713. stream_tag,
  714. fmt == format ? "" : "new-",
  715. format);
  716. if (tag != stream_tag)
  717. snd_hda_codec_write(codec, nid, 0,
  718. AC_VERB_SET_CHANNEL_STREAMID, stream_tag << 4);
  719. if (fmt != format)
  720. snd_hda_codec_write(codec, nid, 0,
  721. AC_VERB_SET_STREAM_FORMAT, format);
  722. }
  723. static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
  724. struct hda_codec *codec,
  725. unsigned int stream_tag,
  726. unsigned int format,
  727. struct snd_pcm_substream *substream)
  728. {
  729. hdmi_set_channel_count(codec, hinfo->nid,
  730. substream->runtime->channels);
  731. hdmi_setup_audio_infoframe(codec, hinfo->nid, substream);
  732. hdmi_setup_stream(codec, hinfo->nid, stream_tag, format);
  733. return 0;
  734. }
  735. static int intel_hdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
  736. struct hda_codec *codec,
  737. struct snd_pcm_substream *substream)
  738. {
  739. return 0;
  740. }
  741. static struct hda_pcm_stream intel_hdmi_pcm_playback = {
  742. .substreams = 1,
  743. .channels_min = 2,
  744. .ops = {
  745. .prepare = intel_hdmi_playback_pcm_prepare,
  746. .cleanup = intel_hdmi_playback_pcm_cleanup,
  747. },
  748. };
  749. static int intel_hdmi_build_pcms(struct hda_codec *codec)
  750. {
  751. struct intel_hdmi_spec *spec = codec->spec;
  752. struct hda_pcm *info = spec->pcm_rec;
  753. int i;
  754. codec->num_pcms = spec->num_cvts;
  755. codec->pcm_info = info;
  756. for (i = 0; i < codec->num_pcms; i++, info++) {
  757. unsigned int chans;
  758. chans = get_wcaps(codec, spec->cvt[i]);
  759. chans = get_wcaps_channels(chans);
  760. info->name = intel_hdmi_pcm_names[i];
  761. info->pcm_type = HDA_PCM_TYPE_HDMI;
  762. info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
  763. intel_hdmi_pcm_playback;
  764. info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->cvt[i];
  765. info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = chans;
  766. }
  767. return 0;
  768. }
  769. static int intel_hdmi_build_controls(struct hda_codec *codec)
  770. {
  771. struct intel_hdmi_spec *spec = codec->spec;
  772. int err;
  773. int i;
  774. for (i = 0; i < codec->num_pcms; i++) {
  775. err = snd_hda_create_spdif_out_ctls(codec, spec->cvt[i]);
  776. if (err < 0)
  777. return err;
  778. }
  779. return 0;
  780. }
  781. static int intel_hdmi_init(struct hda_codec *codec)
  782. {
  783. struct intel_hdmi_spec *spec = codec->spec;
  784. int i;
  785. for (i = 0; spec->pin[i]; i++) {
  786. hdmi_enable_output(codec, spec->pin[i]);
  787. snd_hda_codec_write(codec, spec->pin[i], 0,
  788. AC_VERB_SET_UNSOLICITED_ENABLE,
  789. AC_USRSP_EN | spec->pin[i]);
  790. }
  791. return 0;
  792. }
  793. static void intel_hdmi_free(struct hda_codec *codec)
  794. {
  795. struct intel_hdmi_spec *spec = codec->spec;
  796. int i;
  797. for (i = 0; i < spec->num_pins; i++)
  798. snd_hda_eld_proc_free(codec, &spec->sink_eld[i]);
  799. kfree(spec);
  800. }
  801. static struct hda_codec_ops intel_hdmi_patch_ops = {
  802. .init = intel_hdmi_init,
  803. .free = intel_hdmi_free,
  804. .build_pcms = intel_hdmi_build_pcms,
  805. .build_controls = intel_hdmi_build_controls,
  806. .unsol_event = intel_hdmi_unsol_event,
  807. };
  808. static int patch_intel_hdmi(struct hda_codec *codec)
  809. {
  810. struct intel_hdmi_spec *spec;
  811. int i;
  812. spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  813. if (spec == NULL)
  814. return -ENOMEM;
  815. codec->spec = spec;
  816. if (intel_hdmi_parse_codec(codec) < 0) {
  817. codec->spec = NULL;
  818. kfree(spec);
  819. return -EINVAL;
  820. }
  821. codec->patch_ops = intel_hdmi_patch_ops;
  822. for (i = 0; i < spec->num_pins; i++)
  823. snd_hda_eld_proc_new(codec, &spec->sink_eld[i], i);
  824. init_channel_allocations();
  825. return 0;
  826. }
  827. static struct hda_codec_preset snd_hda_preset_intelhdmi[] = {
  828. { .id = 0x808629fb, .name = "G45 DEVCL", .patch = patch_intel_hdmi },
  829. { .id = 0x80862801, .name = "G45 DEVBLC", .patch = patch_intel_hdmi },
  830. { .id = 0x80862802, .name = "G45 DEVCTG", .patch = patch_intel_hdmi },
  831. { .id = 0x80862803, .name = "G45 DEVELK", .patch = patch_intel_hdmi },
  832. { .id = 0x80862804, .name = "G45 DEVIBX", .patch = patch_intel_hdmi },
  833. { .id = 0x80860054, .name = "Q57 DEVIBX", .patch = patch_intel_hdmi },
  834. { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_intel_hdmi },
  835. {} /* terminator */
  836. };
  837. MODULE_ALIAS("snd-hda-codec-id:808629fb");
  838. MODULE_ALIAS("snd-hda-codec-id:80862801");
  839. MODULE_ALIAS("snd-hda-codec-id:80862802");
  840. MODULE_ALIAS("snd-hda-codec-id:80862803");
  841. MODULE_ALIAS("snd-hda-codec-id:80862804");
  842. MODULE_ALIAS("snd-hda-codec-id:80860054");
  843. MODULE_ALIAS("snd-hda-codec-id:10951392");
  844. MODULE_LICENSE("GPL");
  845. MODULE_DESCRIPTION("Intel HDMI HD-audio codec");
  846. static struct hda_codec_preset_list intel_list = {
  847. .preset = snd_hda_preset_intelhdmi,
  848. .owner = THIS_MODULE,
  849. };
  850. static int __init patch_intelhdmi_init(void)
  851. {
  852. return snd_hda_add_codec_preset(&intel_list);
  853. }
  854. static void __exit patch_intelhdmi_exit(void)
  855. {
  856. snd_hda_delete_codec_preset(&intel_list);
  857. }
  858. module_init(patch_intelhdmi_init)
  859. module_exit(patch_intelhdmi_exit)