2
0

hda-codec.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731
  1. /*
  2. * Copyright (C) 2010 Red Hat, Inc.
  3. *
  4. * written by Gerd Hoffmann <kraxel@redhat.com>
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License as
  8. * published by the Free Software Foundation; either version 2 or
  9. * (at your option) version 3 of the License.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "qemu/osdep.h"
  20. #include "hw/hw.h"
  21. #include "hw/pci/pci.h"
  22. #include "intel-hda.h"
  23. #include "intel-hda-defs.h"
  24. #include "audio/audio.h"
  25. /* -------------------------------------------------------------------------- */
  26. typedef struct desc_param {
  27. uint32_t id;
  28. uint32_t val;
  29. } desc_param;
  30. typedef struct desc_node {
  31. uint32_t nid;
  32. const char *name;
  33. const desc_param *params;
  34. uint32_t nparams;
  35. uint32_t config;
  36. uint32_t pinctl;
  37. uint32_t *conn;
  38. uint32_t stindex;
  39. } desc_node;
  40. typedef struct desc_codec {
  41. const char *name;
  42. uint32_t iid;
  43. const desc_node *nodes;
  44. uint32_t nnodes;
  45. } desc_codec;
  46. static const desc_param* hda_codec_find_param(const desc_node *node, uint32_t id)
  47. {
  48. int i;
  49. for (i = 0; i < node->nparams; i++) {
  50. if (node->params[i].id == id) {
  51. return &node->params[i];
  52. }
  53. }
  54. return NULL;
  55. }
  56. static const desc_node* hda_codec_find_node(const desc_codec *codec, uint32_t nid)
  57. {
  58. int i;
  59. for (i = 0; i < codec->nnodes; i++) {
  60. if (codec->nodes[i].nid == nid) {
  61. return &codec->nodes[i];
  62. }
  63. }
  64. return NULL;
  65. }
  66. static void hda_codec_parse_fmt(uint32_t format, struct audsettings *as)
  67. {
  68. if (format & AC_FMT_TYPE_NON_PCM) {
  69. return;
  70. }
  71. as->freq = (format & AC_FMT_BASE_44K) ? 44100 : 48000;
  72. switch ((format & AC_FMT_MULT_MASK) >> AC_FMT_MULT_SHIFT) {
  73. case 1: as->freq *= 2; break;
  74. case 2: as->freq *= 3; break;
  75. case 3: as->freq *= 4; break;
  76. }
  77. switch ((format & AC_FMT_DIV_MASK) >> AC_FMT_DIV_SHIFT) {
  78. case 1: as->freq /= 2; break;
  79. case 2: as->freq /= 3; break;
  80. case 3: as->freq /= 4; break;
  81. case 4: as->freq /= 5; break;
  82. case 5: as->freq /= 6; break;
  83. case 6: as->freq /= 7; break;
  84. case 7: as->freq /= 8; break;
  85. }
  86. switch (format & AC_FMT_BITS_MASK) {
  87. case AC_FMT_BITS_8: as->fmt = AUD_FMT_S8; break;
  88. case AC_FMT_BITS_16: as->fmt = AUD_FMT_S16; break;
  89. case AC_FMT_BITS_32: as->fmt = AUD_FMT_S32; break;
  90. }
  91. as->nchannels = ((format & AC_FMT_CHAN_MASK) >> AC_FMT_CHAN_SHIFT) + 1;
  92. }
  93. /* -------------------------------------------------------------------------- */
  94. /*
  95. * HDA codec descriptions
  96. */
  97. /* some defines */
  98. #define QEMU_HDA_ID_VENDOR 0x1af4
  99. #define QEMU_HDA_PCM_FORMATS (AC_SUPPCM_BITS_16 | \
  100. 0x1fc /* 16 -> 96 kHz */)
  101. #define QEMU_HDA_AMP_NONE (0)
  102. #define QEMU_HDA_AMP_STEPS 0x4a
  103. #define PARAM mixemu
  104. #define HDA_MIXER
  105. #include "hda-codec-common.h"
  106. #define PARAM nomixemu
  107. #include "hda-codec-common.h"
  108. /* -------------------------------------------------------------------------- */
  109. static const char *fmt2name[] = {
  110. [ AUD_FMT_U8 ] = "PCM-U8",
  111. [ AUD_FMT_S8 ] = "PCM-S8",
  112. [ AUD_FMT_U16 ] = "PCM-U16",
  113. [ AUD_FMT_S16 ] = "PCM-S16",
  114. [ AUD_FMT_U32 ] = "PCM-U32",
  115. [ AUD_FMT_S32 ] = "PCM-S32",
  116. };
  117. typedef struct HDAAudioState HDAAudioState;
  118. typedef struct HDAAudioStream HDAAudioStream;
  119. struct HDAAudioStream {
  120. HDAAudioState *state;
  121. const desc_node *node;
  122. bool output, running;
  123. uint32_t stream;
  124. uint32_t channel;
  125. uint32_t format;
  126. uint32_t gain_left, gain_right;
  127. bool mute_left, mute_right;
  128. struct audsettings as;
  129. union {
  130. SWVoiceIn *in;
  131. SWVoiceOut *out;
  132. } voice;
  133. uint8_t buf[HDA_BUFFER_SIZE];
  134. uint32_t bpos;
  135. };
  136. #define TYPE_HDA_AUDIO "hda-audio"
  137. #define HDA_AUDIO(obj) OBJECT_CHECK(HDAAudioState, (obj), TYPE_HDA_AUDIO)
  138. struct HDAAudioState {
  139. HDACodecDevice hda;
  140. const char *name;
  141. QEMUSoundCard card;
  142. const desc_codec *desc;
  143. HDAAudioStream st[4];
  144. bool running_compat[16];
  145. bool running_real[2 * 16];
  146. /* properties */
  147. uint32_t debug;
  148. bool mixer;
  149. };
  150. static void hda_audio_input_cb(void *opaque, int avail)
  151. {
  152. HDAAudioStream *st = opaque;
  153. int recv = 0;
  154. int len;
  155. bool rc;
  156. while (avail - recv >= sizeof(st->buf)) {
  157. if (st->bpos != sizeof(st->buf)) {
  158. len = AUD_read(st->voice.in, st->buf + st->bpos,
  159. sizeof(st->buf) - st->bpos);
  160. st->bpos += len;
  161. recv += len;
  162. if (st->bpos != sizeof(st->buf)) {
  163. break;
  164. }
  165. }
  166. rc = hda_codec_xfer(&st->state->hda, st->stream, false,
  167. st->buf, sizeof(st->buf));
  168. if (!rc) {
  169. break;
  170. }
  171. st->bpos = 0;
  172. }
  173. }
  174. static void hda_audio_output_cb(void *opaque, int avail)
  175. {
  176. HDAAudioStream *st = opaque;
  177. int sent = 0;
  178. int len;
  179. bool rc;
  180. while (avail - sent >= sizeof(st->buf)) {
  181. if (st->bpos == sizeof(st->buf)) {
  182. rc = hda_codec_xfer(&st->state->hda, st->stream, true,
  183. st->buf, sizeof(st->buf));
  184. if (!rc) {
  185. break;
  186. }
  187. st->bpos = 0;
  188. }
  189. len = AUD_write(st->voice.out, st->buf + st->bpos,
  190. sizeof(st->buf) - st->bpos);
  191. st->bpos += len;
  192. sent += len;
  193. if (st->bpos != sizeof(st->buf)) {
  194. break;
  195. }
  196. }
  197. }
  198. static void hda_audio_set_running(HDAAudioStream *st, bool running)
  199. {
  200. if (st->node == NULL) {
  201. return;
  202. }
  203. if (st->running == running) {
  204. return;
  205. }
  206. st->running = running;
  207. dprint(st->state, 1, "%s: %s (stream %d)\n", st->node->name,
  208. st->running ? "on" : "off", st->stream);
  209. if (st->output) {
  210. AUD_set_active_out(st->voice.out, st->running);
  211. } else {
  212. AUD_set_active_in(st->voice.in, st->running);
  213. }
  214. }
  215. static void hda_audio_set_amp(HDAAudioStream *st)
  216. {
  217. bool muted;
  218. uint32_t left, right;
  219. if (st->node == NULL) {
  220. return;
  221. }
  222. muted = st->mute_left && st->mute_right;
  223. left = st->mute_left ? 0 : st->gain_left;
  224. right = st->mute_right ? 0 : st->gain_right;
  225. left = left * 255 / QEMU_HDA_AMP_STEPS;
  226. right = right * 255 / QEMU_HDA_AMP_STEPS;
  227. if (!st->state->mixer) {
  228. return;
  229. }
  230. if (st->output) {
  231. AUD_set_volume_out(st->voice.out, muted, left, right);
  232. } else {
  233. AUD_set_volume_in(st->voice.in, muted, left, right);
  234. }
  235. }
  236. static void hda_audio_setup(HDAAudioStream *st)
  237. {
  238. if (st->node == NULL) {
  239. return;
  240. }
  241. dprint(st->state, 1, "%s: format: %d x %s @ %d Hz\n",
  242. st->node->name, st->as.nchannels,
  243. fmt2name[st->as.fmt], st->as.freq);
  244. if (st->output) {
  245. st->voice.out = AUD_open_out(&st->state->card, st->voice.out,
  246. st->node->name, st,
  247. hda_audio_output_cb, &st->as);
  248. } else {
  249. st->voice.in = AUD_open_in(&st->state->card, st->voice.in,
  250. st->node->name, st,
  251. hda_audio_input_cb, &st->as);
  252. }
  253. }
  254. static void hda_audio_command(HDACodecDevice *hda, uint32_t nid, uint32_t data)
  255. {
  256. HDAAudioState *a = HDA_AUDIO(hda);
  257. HDAAudioStream *st;
  258. const desc_node *node = NULL;
  259. const desc_param *param;
  260. uint32_t verb, payload, response, count, shift;
  261. if ((data & 0x70000) == 0x70000) {
  262. /* 12/8 id/payload */
  263. verb = (data >> 8) & 0xfff;
  264. payload = data & 0x00ff;
  265. } else {
  266. /* 4/16 id/payload */
  267. verb = (data >> 8) & 0xf00;
  268. payload = data & 0xffff;
  269. }
  270. node = hda_codec_find_node(a->desc, nid);
  271. if (node == NULL) {
  272. goto fail;
  273. }
  274. dprint(a, 2, "%s: nid %d (%s), verb 0x%x, payload 0x%x\n",
  275. __func__, nid, node->name, verb, payload);
  276. switch (verb) {
  277. /* all nodes */
  278. case AC_VERB_PARAMETERS:
  279. param = hda_codec_find_param(node, payload);
  280. if (param == NULL) {
  281. goto fail;
  282. }
  283. hda_codec_response(hda, true, param->val);
  284. break;
  285. case AC_VERB_GET_SUBSYSTEM_ID:
  286. hda_codec_response(hda, true, a->desc->iid);
  287. break;
  288. /* all functions */
  289. case AC_VERB_GET_CONNECT_LIST:
  290. param = hda_codec_find_param(node, AC_PAR_CONNLIST_LEN);
  291. count = param ? param->val : 0;
  292. response = 0;
  293. shift = 0;
  294. while (payload < count && shift < 32) {
  295. response |= node->conn[payload] << shift;
  296. payload++;
  297. shift += 8;
  298. }
  299. hda_codec_response(hda, true, response);
  300. break;
  301. /* pin widget */
  302. case AC_VERB_GET_CONFIG_DEFAULT:
  303. hda_codec_response(hda, true, node->config);
  304. break;
  305. case AC_VERB_GET_PIN_WIDGET_CONTROL:
  306. hda_codec_response(hda, true, node->pinctl);
  307. break;
  308. case AC_VERB_SET_PIN_WIDGET_CONTROL:
  309. if (node->pinctl != payload) {
  310. dprint(a, 1, "unhandled pin control bit\n");
  311. }
  312. hda_codec_response(hda, true, 0);
  313. break;
  314. /* audio in/out widget */
  315. case AC_VERB_SET_CHANNEL_STREAMID:
  316. st = a->st + node->stindex;
  317. if (st->node == NULL) {
  318. goto fail;
  319. }
  320. hda_audio_set_running(st, false);
  321. st->stream = (payload >> 4) & 0x0f;
  322. st->channel = payload & 0x0f;
  323. dprint(a, 2, "%s: stream %d, channel %d\n",
  324. st->node->name, st->stream, st->channel);
  325. hda_audio_set_running(st, a->running_real[st->output * 16 + st->stream]);
  326. hda_codec_response(hda, true, 0);
  327. break;
  328. case AC_VERB_GET_CONV:
  329. st = a->st + node->stindex;
  330. if (st->node == NULL) {
  331. goto fail;
  332. }
  333. response = st->stream << 4 | st->channel;
  334. hda_codec_response(hda, true, response);
  335. break;
  336. case AC_VERB_SET_STREAM_FORMAT:
  337. st = a->st + node->stindex;
  338. if (st->node == NULL) {
  339. goto fail;
  340. }
  341. st->format = payload;
  342. hda_codec_parse_fmt(st->format, &st->as);
  343. hda_audio_setup(st);
  344. hda_codec_response(hda, true, 0);
  345. break;
  346. case AC_VERB_GET_STREAM_FORMAT:
  347. st = a->st + node->stindex;
  348. if (st->node == NULL) {
  349. goto fail;
  350. }
  351. hda_codec_response(hda, true, st->format);
  352. break;
  353. case AC_VERB_GET_AMP_GAIN_MUTE:
  354. st = a->st + node->stindex;
  355. if (st->node == NULL) {
  356. goto fail;
  357. }
  358. if (payload & AC_AMP_GET_LEFT) {
  359. response = st->gain_left | (st->mute_left ? AC_AMP_MUTE : 0);
  360. } else {
  361. response = st->gain_right | (st->mute_right ? AC_AMP_MUTE : 0);
  362. }
  363. hda_codec_response(hda, true, response);
  364. break;
  365. case AC_VERB_SET_AMP_GAIN_MUTE:
  366. st = a->st + node->stindex;
  367. if (st->node == NULL) {
  368. goto fail;
  369. }
  370. dprint(a, 1, "amp (%s): %s%s%s%s index %d gain %3d %s\n",
  371. st->node->name,
  372. (payload & AC_AMP_SET_OUTPUT) ? "o" : "-",
  373. (payload & AC_AMP_SET_INPUT) ? "i" : "-",
  374. (payload & AC_AMP_SET_LEFT) ? "l" : "-",
  375. (payload & AC_AMP_SET_RIGHT) ? "r" : "-",
  376. (payload & AC_AMP_SET_INDEX) >> AC_AMP_SET_INDEX_SHIFT,
  377. (payload & AC_AMP_GAIN),
  378. (payload & AC_AMP_MUTE) ? "muted" : "");
  379. if (payload & AC_AMP_SET_LEFT) {
  380. st->gain_left = payload & AC_AMP_GAIN;
  381. st->mute_left = payload & AC_AMP_MUTE;
  382. }
  383. if (payload & AC_AMP_SET_RIGHT) {
  384. st->gain_right = payload & AC_AMP_GAIN;
  385. st->mute_right = payload & AC_AMP_MUTE;
  386. }
  387. hda_audio_set_amp(st);
  388. hda_codec_response(hda, true, 0);
  389. break;
  390. /* not supported */
  391. case AC_VERB_SET_POWER_STATE:
  392. case AC_VERB_GET_POWER_STATE:
  393. case AC_VERB_GET_SDI_SELECT:
  394. hda_codec_response(hda, true, 0);
  395. break;
  396. default:
  397. goto fail;
  398. }
  399. return;
  400. fail:
  401. dprint(a, 1, "%s: not handled: nid %d (%s), verb 0x%x, payload 0x%x\n",
  402. __func__, nid, node ? node->name : "?", verb, payload);
  403. hda_codec_response(hda, true, 0);
  404. }
  405. static void hda_audio_stream(HDACodecDevice *hda, uint32_t stnr, bool running, bool output)
  406. {
  407. HDAAudioState *a = HDA_AUDIO(hda);
  408. int s;
  409. a->running_compat[stnr] = running;
  410. a->running_real[output * 16 + stnr] = running;
  411. for (s = 0; s < ARRAY_SIZE(a->st); s++) {
  412. if (a->st[s].node == NULL) {
  413. continue;
  414. }
  415. if (a->st[s].output != output) {
  416. continue;
  417. }
  418. if (a->st[s].stream != stnr) {
  419. continue;
  420. }
  421. hda_audio_set_running(&a->st[s], running);
  422. }
  423. }
  424. static int hda_audio_init(HDACodecDevice *hda, const struct desc_codec *desc)
  425. {
  426. HDAAudioState *a = HDA_AUDIO(hda);
  427. HDAAudioStream *st;
  428. const desc_node *node;
  429. const desc_param *param;
  430. uint32_t i, type;
  431. a->desc = desc;
  432. a->name = object_get_typename(OBJECT(a));
  433. dprint(a, 1, "%s: cad %d\n", __func__, a->hda.cad);
  434. AUD_register_card("hda", &a->card);
  435. for (i = 0; i < a->desc->nnodes; i++) {
  436. node = a->desc->nodes + i;
  437. param = hda_codec_find_param(node, AC_PAR_AUDIO_WIDGET_CAP);
  438. if (param == NULL) {
  439. continue;
  440. }
  441. type = (param->val & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
  442. switch (type) {
  443. case AC_WID_AUD_OUT:
  444. case AC_WID_AUD_IN:
  445. assert(node->stindex < ARRAY_SIZE(a->st));
  446. st = a->st + node->stindex;
  447. st->state = a;
  448. st->node = node;
  449. if (type == AC_WID_AUD_OUT) {
  450. /* unmute output by default */
  451. st->gain_left = QEMU_HDA_AMP_STEPS;
  452. st->gain_right = QEMU_HDA_AMP_STEPS;
  453. st->bpos = sizeof(st->buf);
  454. st->output = true;
  455. } else {
  456. st->output = false;
  457. }
  458. st->format = AC_FMT_TYPE_PCM | AC_FMT_BITS_16 |
  459. (1 << AC_FMT_CHAN_SHIFT);
  460. hda_codec_parse_fmt(st->format, &st->as);
  461. hda_audio_setup(st);
  462. break;
  463. }
  464. }
  465. return 0;
  466. }
  467. static void hda_audio_exit(HDACodecDevice *hda)
  468. {
  469. HDAAudioState *a = HDA_AUDIO(hda);
  470. HDAAudioStream *st;
  471. int i;
  472. dprint(a, 1, "%s\n", __func__);
  473. for (i = 0; i < ARRAY_SIZE(a->st); i++) {
  474. st = a->st + i;
  475. if (st->node == NULL) {
  476. continue;
  477. }
  478. if (st->output) {
  479. AUD_close_out(&a->card, st->voice.out);
  480. } else {
  481. AUD_close_in(&a->card, st->voice.in);
  482. }
  483. }
  484. AUD_remove_card(&a->card);
  485. }
  486. static int hda_audio_post_load(void *opaque, int version)
  487. {
  488. HDAAudioState *a = opaque;
  489. HDAAudioStream *st;
  490. int i;
  491. dprint(a, 1, "%s\n", __func__);
  492. if (version == 1) {
  493. /* assume running_compat[] is for output streams */
  494. for (i = 0; i < ARRAY_SIZE(a->running_compat); i++)
  495. a->running_real[16 + i] = a->running_compat[i];
  496. }
  497. for (i = 0; i < ARRAY_SIZE(a->st); i++) {
  498. st = a->st + i;
  499. if (st->node == NULL)
  500. continue;
  501. hda_codec_parse_fmt(st->format, &st->as);
  502. hda_audio_setup(st);
  503. hda_audio_set_amp(st);
  504. hda_audio_set_running(st, a->running_real[st->output * 16 + st->stream]);
  505. }
  506. return 0;
  507. }
  508. static void hda_audio_reset(DeviceState *dev)
  509. {
  510. HDAAudioState *a = HDA_AUDIO(dev);
  511. HDAAudioStream *st;
  512. int i;
  513. dprint(a, 1, "%s\n", __func__);
  514. for (i = 0; i < ARRAY_SIZE(a->st); i++) {
  515. st = a->st + i;
  516. if (st->node != NULL) {
  517. hda_audio_set_running(st, false);
  518. }
  519. }
  520. }
  521. static const VMStateDescription vmstate_hda_audio_stream = {
  522. .name = "hda-audio-stream",
  523. .version_id = 1,
  524. .fields = (VMStateField[]) {
  525. VMSTATE_UINT32(stream, HDAAudioStream),
  526. VMSTATE_UINT32(channel, HDAAudioStream),
  527. VMSTATE_UINT32(format, HDAAudioStream),
  528. VMSTATE_UINT32(gain_left, HDAAudioStream),
  529. VMSTATE_UINT32(gain_right, HDAAudioStream),
  530. VMSTATE_BOOL(mute_left, HDAAudioStream),
  531. VMSTATE_BOOL(mute_right, HDAAudioStream),
  532. VMSTATE_UINT32(bpos, HDAAudioStream),
  533. VMSTATE_BUFFER(buf, HDAAudioStream),
  534. VMSTATE_END_OF_LIST()
  535. }
  536. };
  537. static const VMStateDescription vmstate_hda_audio = {
  538. .name = "hda-audio",
  539. .version_id = 2,
  540. .post_load = hda_audio_post_load,
  541. .fields = (VMStateField[]) {
  542. VMSTATE_STRUCT_ARRAY(st, HDAAudioState, 4, 0,
  543. vmstate_hda_audio_stream,
  544. HDAAudioStream),
  545. VMSTATE_BOOL_ARRAY(running_compat, HDAAudioState, 16),
  546. VMSTATE_BOOL_ARRAY_V(running_real, HDAAudioState, 2 * 16, 2),
  547. VMSTATE_END_OF_LIST()
  548. }
  549. };
  550. static Property hda_audio_properties[] = {
  551. DEFINE_PROP_UINT32("debug", HDAAudioState, debug, 0),
  552. DEFINE_PROP_BOOL("mixer", HDAAudioState, mixer, true),
  553. DEFINE_PROP_END_OF_LIST(),
  554. };
  555. static int hda_audio_init_output(HDACodecDevice *hda)
  556. {
  557. HDAAudioState *a = HDA_AUDIO(hda);
  558. if (!a->mixer) {
  559. return hda_audio_init(hda, &output_nomixemu);
  560. } else {
  561. return hda_audio_init(hda, &output_mixemu);
  562. }
  563. }
  564. static int hda_audio_init_duplex(HDACodecDevice *hda)
  565. {
  566. HDAAudioState *a = HDA_AUDIO(hda);
  567. if (!a->mixer) {
  568. return hda_audio_init(hda, &duplex_nomixemu);
  569. } else {
  570. return hda_audio_init(hda, &duplex_mixemu);
  571. }
  572. }
  573. static int hda_audio_init_micro(HDACodecDevice *hda)
  574. {
  575. HDAAudioState *a = HDA_AUDIO(hda);
  576. if (!a->mixer) {
  577. return hda_audio_init(hda, &micro_nomixemu);
  578. } else {
  579. return hda_audio_init(hda, &micro_mixemu);
  580. }
  581. }
  582. static void hda_audio_base_class_init(ObjectClass *klass, void *data)
  583. {
  584. DeviceClass *dc = DEVICE_CLASS(klass);
  585. HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass);
  586. k->exit = hda_audio_exit;
  587. k->command = hda_audio_command;
  588. k->stream = hda_audio_stream;
  589. set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
  590. dc->reset = hda_audio_reset;
  591. dc->vmsd = &vmstate_hda_audio;
  592. dc->props = hda_audio_properties;
  593. }
  594. static const TypeInfo hda_audio_info = {
  595. .name = TYPE_HDA_AUDIO,
  596. .parent = TYPE_HDA_CODEC_DEVICE,
  597. .class_init = hda_audio_base_class_init,
  598. .abstract = true,
  599. };
  600. static void hda_audio_output_class_init(ObjectClass *klass, void *data)
  601. {
  602. DeviceClass *dc = DEVICE_CLASS(klass);
  603. HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass);
  604. k->init = hda_audio_init_output;
  605. dc->desc = "HDA Audio Codec, output-only (line-out)";
  606. }
  607. static const TypeInfo hda_audio_output_info = {
  608. .name = "hda-output",
  609. .parent = TYPE_HDA_AUDIO,
  610. .instance_size = sizeof(HDAAudioState),
  611. .class_init = hda_audio_output_class_init,
  612. };
  613. static void hda_audio_duplex_class_init(ObjectClass *klass, void *data)
  614. {
  615. DeviceClass *dc = DEVICE_CLASS(klass);
  616. HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass);
  617. k->init = hda_audio_init_duplex;
  618. dc->desc = "HDA Audio Codec, duplex (line-out, line-in)";
  619. }
  620. static const TypeInfo hda_audio_duplex_info = {
  621. .name = "hda-duplex",
  622. .parent = TYPE_HDA_AUDIO,
  623. .instance_size = sizeof(HDAAudioState),
  624. .class_init = hda_audio_duplex_class_init,
  625. };
  626. static void hda_audio_micro_class_init(ObjectClass *klass, void *data)
  627. {
  628. DeviceClass *dc = DEVICE_CLASS(klass);
  629. HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass);
  630. k->init = hda_audio_init_micro;
  631. dc->desc = "HDA Audio Codec, duplex (speaker, microphone)";
  632. }
  633. static const TypeInfo hda_audio_micro_info = {
  634. .name = "hda-micro",
  635. .parent = TYPE_HDA_AUDIO,
  636. .instance_size = sizeof(HDAAudioState),
  637. .class_init = hda_audio_micro_class_init,
  638. };
  639. static void hda_audio_register_types(void)
  640. {
  641. type_register_static(&hda_audio_info);
  642. type_register_static(&hda_audio_output_info);
  643. type_register_static(&hda_audio_duplex_info);
  644. type_register_static(&hda_audio_micro_info);
  645. }
  646. type_init(hda_audio_register_types)