lola_mixer.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Support for Digigram Lola PCI-e boards
  4. *
  5. * Copyright (c) 2011 Takashi Iwai <[email protected]>
  6. */
  7. #include <linux/kernel.h>
  8. #include <linux/init.h>
  9. #include <linux/vmalloc.h>
  10. #include <linux/io.h>
  11. #include <sound/core.h>
  12. #include <sound/control.h>
  13. #include <sound/pcm.h>
  14. #include <sound/tlv.h>
  15. #include "lola.h"
  16. static int lola_init_pin(struct lola *chip, struct lola_pin *pin,
  17. int dir, int nid)
  18. {
  19. unsigned int val;
  20. int err;
  21. pin->nid = nid;
  22. err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
  23. if (err < 0) {
  24. dev_err(chip->card->dev, "Can't read wcaps for 0x%x\n", nid);
  25. return err;
  26. }
  27. val &= 0x00f00fff; /* test TYPE and bits 0..11 */
  28. if (val == 0x00400200) /* Type = 4, Digital = 1 */
  29. pin->is_analog = false;
  30. else if (val == 0x0040000a && dir == CAPT) /* Dig=0, InAmp/ovrd */
  31. pin->is_analog = true;
  32. else if (val == 0x0040000c && dir == PLAY) /* Dig=0, OutAmp/ovrd */
  33. pin->is_analog = true;
  34. else {
  35. dev_err(chip->card->dev, "Invalid wcaps 0x%x for 0x%x\n", val, nid);
  36. return -EINVAL;
  37. }
  38. /* analog parameters only following, so continue in case of Digital pin
  39. */
  40. if (!pin->is_analog)
  41. return 0;
  42. if (dir == PLAY)
  43. err = lola_read_param(chip, nid, LOLA_PAR_AMP_OUT_CAP, &val);
  44. else
  45. err = lola_read_param(chip, nid, LOLA_PAR_AMP_IN_CAP, &val);
  46. if (err < 0) {
  47. dev_err(chip->card->dev, "Can't read AMP-caps for 0x%x\n", nid);
  48. return err;
  49. }
  50. pin->amp_mute = LOLA_AMP_MUTE_CAPABLE(val);
  51. pin->amp_step_size = LOLA_AMP_STEP_SIZE(val);
  52. pin->amp_num_steps = LOLA_AMP_NUM_STEPS(val);
  53. if (pin->amp_num_steps) {
  54. /* zero as mute state */
  55. pin->amp_num_steps++;
  56. pin->amp_step_size++;
  57. }
  58. pin->amp_offset = LOLA_AMP_OFFSET(val);
  59. err = lola_codec_read(chip, nid, LOLA_VERB_GET_MAX_LEVEL, 0, 0, &val,
  60. NULL);
  61. if (err < 0) {
  62. dev_err(chip->card->dev, "Can't get MAX_LEVEL 0x%x\n", nid);
  63. return err;
  64. }
  65. pin->max_level = val & 0x3ff; /* 10 bits */
  66. pin->config_default_reg = 0;
  67. pin->fixed_gain_list_len = 0;
  68. pin->cur_gain_step = 0;
  69. return 0;
  70. }
  71. int lola_init_pins(struct lola *chip, int dir, int *nidp)
  72. {
  73. int i, err, nid;
  74. nid = *nidp;
  75. for (i = 0; i < chip->pin[dir].num_pins; i++, nid++) {
  76. err = lola_init_pin(chip, &chip->pin[dir].pins[i], dir, nid);
  77. if (err < 0)
  78. return err;
  79. if (chip->pin[dir].pins[i].is_analog)
  80. chip->pin[dir].num_analog_pins++;
  81. }
  82. *nidp = nid;
  83. return 0;
  84. }
  85. void lola_free_mixer(struct lola *chip)
  86. {
  87. vfree(chip->mixer.array_saved);
  88. }
  89. int lola_init_mixer_widget(struct lola *chip, int nid)
  90. {
  91. unsigned int val;
  92. int err;
  93. err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);
  94. if (err < 0) {
  95. dev_err(chip->card->dev, "Can't read wcaps for 0x%x\n", nid);
  96. return err;
  97. }
  98. if ((val & 0xfff00000) != 0x02f00000) { /* test SubType and Type */
  99. dev_dbg(chip->card->dev, "No valid mixer widget\n");
  100. return 0;
  101. }
  102. chip->mixer.nid = nid;
  103. chip->mixer.caps = val;
  104. chip->mixer.array = (struct lola_mixer_array __iomem *)
  105. (chip->bar[BAR1].remap_addr + LOLA_BAR1_SOURCE_GAIN_ENABLE);
  106. /* reserve memory to copy mixer data for sleep mode transitions */
  107. chip->mixer.array_saved = vmalloc(sizeof(struct lola_mixer_array));
  108. if (!chip->mixer.array_saved)
  109. return -ENOMEM;
  110. /* mixer matrix sources are physical input data and play streams */
  111. chip->mixer.src_stream_outs = chip->pcm[PLAY].num_streams;
  112. chip->mixer.src_phys_ins = chip->pin[CAPT].num_pins;
  113. /* mixer matrix destinations are record streams and physical output */
  114. chip->mixer.dest_stream_ins = chip->pcm[CAPT].num_streams;
  115. chip->mixer.dest_phys_outs = chip->pin[PLAY].num_pins;
  116. /* mixer matrix may have unused areas between PhysIn and
  117. * Play or Record and PhysOut zones
  118. */
  119. chip->mixer.src_stream_out_ofs = chip->mixer.src_phys_ins +
  120. LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(val);
  121. chip->mixer.dest_phys_out_ofs = chip->mixer.dest_stream_ins +
  122. LOLA_MIXER_DEST_REC_OUTPUT_SEPARATION(val);
  123. /* example : MixerMatrix of LoLa881 (LoLa16161 uses unused zones)
  124. * +-+ 0-------8------16-------8------16
  125. * | | | | | | |
  126. * |s| | INPUT | | INPUT | |
  127. * | |->| -> |unused | -> |unused |
  128. * |r| |CAPTURE| | OUTPUT| |
  129. * | | | MIX | | MIX | |
  130. * |c| 8--------------------------------
  131. * | | | | | | |
  132. * | | | | | | |
  133. * |g| |unused |unused |unused |unused |
  134. * | | | | | | |
  135. * |a| | | | | |
  136. * | | 16-------------------------------
  137. * |i| | | | | |
  138. * | | | PLAYBK| | PLAYBK| |
  139. * |n|->| -> |unused | -> |unused |
  140. * | | |CAPTURE| | OUTPUT| |
  141. * | | | MIX | | MIX | |
  142. * |a| 8--------------------------------
  143. * |r| | | | | |
  144. * |r| | | | | |
  145. * |a| |unused |unused |unused |unused |
  146. * |y| | | | | |
  147. * | | | | | | |
  148. * +++ 16--|---------------|------------
  149. * +---V---------------V-----------+
  150. * | dest_mix_gain_enable array |
  151. * +-------------------------------+
  152. */
  153. /* example : MixerMatrix of LoLa280
  154. * +-+ 0-------8-2
  155. * | | | | |
  156. * |s| | INPUT | | INPUT
  157. * |r|->| -> | | ->
  158. * |c| |CAPTURE| | <- OUTPUT
  159. * | | | MIX | | MIX
  160. * |g| 8----------
  161. * |a| | | |
  162. * |i| | PLAYBK| | PLAYBACK
  163. * |n|->| -> | | ->
  164. * | | |CAPTURE| | <- OUTPUT
  165. * |a| | MIX | | MIX
  166. * |r| 8---|----|-
  167. * |r| +---V----V-------------------+
  168. * |a| | dest_mix_gain_enable array |
  169. * |y| +----------------------------+
  170. */
  171. if (chip->mixer.src_stream_out_ofs > MAX_AUDIO_INOUT_COUNT ||
  172. chip->mixer.dest_phys_out_ofs > MAX_STREAM_IN_COUNT) {
  173. dev_err(chip->card->dev, "Invalid mixer widget size\n");
  174. return -EINVAL;
  175. }
  176. chip->mixer.src_mask = ((1U << chip->mixer.src_phys_ins) - 1) |
  177. (((1U << chip->mixer.src_stream_outs) - 1)
  178. << chip->mixer.src_stream_out_ofs);
  179. chip->mixer.dest_mask = ((1U << chip->mixer.dest_stream_ins) - 1) |
  180. (((1U << chip->mixer.dest_phys_outs) - 1)
  181. << chip->mixer.dest_phys_out_ofs);
  182. dev_dbg(chip->card->dev, "Mixer src_mask=%x, dest_mask=%x\n",
  183. chip->mixer.src_mask, chip->mixer.dest_mask);
  184. return 0;
  185. }
  186. static int lola_mixer_set_src_gain(struct lola *chip, unsigned int id,
  187. unsigned short gain, bool on)
  188. {
  189. unsigned int oldval, val;
  190. if (!(chip->mixer.src_mask & (1 << id)))
  191. return -EINVAL;
  192. oldval = val = readl(&chip->mixer.array->src_gain_enable);
  193. if (on)
  194. val |= (1 << id);
  195. else
  196. val &= ~(1 << id);
  197. /* test if values unchanged */
  198. if ((val == oldval) &&
  199. (gain == readw(&chip->mixer.array->src_gain[id])))
  200. return 0;
  201. dev_dbg(chip->card->dev,
  202. "lola_mixer_set_src_gain (id=%d, gain=%d) enable=%x\n",
  203. id, gain, val);
  204. writew(gain, &chip->mixer.array->src_gain[id]);
  205. writel(val, &chip->mixer.array->src_gain_enable);
  206. lola_codec_flush(chip);
  207. /* inform micro-controller about the new source gain */
  208. return lola_codec_write(chip, chip->mixer.nid,
  209. LOLA_VERB_SET_SOURCE_GAIN, id, 0);
  210. }
  211. #if 0 /* not used */
  212. static int lola_mixer_set_src_gains(struct lola *chip, unsigned int mask,
  213. unsigned short *gains)
  214. {
  215. int i;
  216. if ((chip->mixer.src_mask & mask) != mask)
  217. return -EINVAL;
  218. for (i = 0; i < LOLA_MIXER_DIM; i++) {
  219. if (mask & (1 << i)) {
  220. writew(*gains, &chip->mixer.array->src_gain[i]);
  221. gains++;
  222. }
  223. }
  224. writel(mask, &chip->mixer.array->src_gain_enable);
  225. lola_codec_flush(chip);
  226. if (chip->mixer.caps & LOLA_PEAK_METER_CAN_AGC_MASK) {
  227. /* update for all srcs at once */
  228. return lola_codec_write(chip, chip->mixer.nid,
  229. LOLA_VERB_SET_SOURCE_GAIN, 0x80, 0);
  230. }
  231. /* update manually */
  232. for (i = 0; i < LOLA_MIXER_DIM; i++) {
  233. if (mask & (1 << i)) {
  234. lola_codec_write(chip, chip->mixer.nid,
  235. LOLA_VERB_SET_SOURCE_GAIN, i, 0);
  236. }
  237. }
  238. return 0;
  239. }
  240. #endif /* not used */
  241. static int lola_mixer_set_mapping_gain(struct lola *chip,
  242. unsigned int src, unsigned int dest,
  243. unsigned short gain, bool on)
  244. {
  245. unsigned int val;
  246. if (!(chip->mixer.src_mask & (1 << src)) ||
  247. !(chip->mixer.dest_mask & (1 << dest)))
  248. return -EINVAL;
  249. if (on)
  250. writew(gain, &chip->mixer.array->dest_mix_gain[dest][src]);
  251. val = readl(&chip->mixer.array->dest_mix_gain_enable[dest]);
  252. if (on)
  253. val |= (1 << src);
  254. else
  255. val &= ~(1 << src);
  256. writel(val, &chip->mixer.array->dest_mix_gain_enable[dest]);
  257. lola_codec_flush(chip);
  258. return lola_codec_write(chip, chip->mixer.nid, LOLA_VERB_SET_MIX_GAIN,
  259. src, dest);
  260. }
  261. #if 0 /* not used */
  262. static int lola_mixer_set_dest_gains(struct lola *chip, unsigned int id,
  263. unsigned int mask, unsigned short *gains)
  264. {
  265. int i;
  266. if (!(chip->mixer.dest_mask & (1 << id)) ||
  267. (chip->mixer.src_mask & mask) != mask)
  268. return -EINVAL;
  269. for (i = 0; i < LOLA_MIXER_DIM; i++) {
  270. if (mask & (1 << i)) {
  271. writew(*gains, &chip->mixer.array->dest_mix_gain[id][i]);
  272. gains++;
  273. }
  274. }
  275. writel(mask, &chip->mixer.array->dest_mix_gain_enable[id]);
  276. lola_codec_flush(chip);
  277. /* update for all dests at once */
  278. return lola_codec_write(chip, chip->mixer.nid,
  279. LOLA_VERB_SET_DESTINATION_GAIN, id, 0);
  280. }
  281. #endif /* not used */
  282. /*
  283. */
  284. static int set_analog_volume(struct lola *chip, int dir,
  285. unsigned int idx, unsigned int val,
  286. bool external_call);
  287. int lola_setup_all_analog_gains(struct lola *chip, int dir, bool mute)
  288. {
  289. struct lola_pin *pin;
  290. int idx, max_idx;
  291. pin = chip->pin[dir].pins;
  292. max_idx = chip->pin[dir].num_pins;
  293. for (idx = 0; idx < max_idx; idx++) {
  294. if (pin[idx].is_analog) {
  295. unsigned int val = mute ? 0 : pin[idx].cur_gain_step;
  296. /* set volume and do not save the value */
  297. set_analog_volume(chip, dir, idx, val, false);
  298. }
  299. }
  300. return lola_codec_flush(chip);
  301. }
  302. void lola_save_mixer(struct lola *chip)
  303. {
  304. /* mute analog output */
  305. if (chip->mixer.array_saved) {
  306. /* store contents of mixer array */
  307. memcpy_fromio(chip->mixer.array_saved, chip->mixer.array,
  308. sizeof(*chip->mixer.array));
  309. }
  310. lola_setup_all_analog_gains(chip, PLAY, true); /* output mute */
  311. }
  312. void lola_restore_mixer(struct lola *chip)
  313. {
  314. int i;
  315. /*lola_reset_setups(chip);*/
  316. if (chip->mixer.array_saved) {
  317. /* restore contents of mixer array */
  318. memcpy_toio(chip->mixer.array, chip->mixer.array_saved,
  319. sizeof(*chip->mixer.array));
  320. /* inform micro-controller about all restored values
  321. * and ignore return values
  322. */
  323. for (i = 0; i < chip->mixer.src_phys_ins; i++)
  324. lola_codec_write(chip, chip->mixer.nid,
  325. LOLA_VERB_SET_SOURCE_GAIN,
  326. i, 0);
  327. for (i = 0; i < chip->mixer.src_stream_outs; i++)
  328. lola_codec_write(chip, chip->mixer.nid,
  329. LOLA_VERB_SET_SOURCE_GAIN,
  330. chip->mixer.src_stream_out_ofs + i, 0);
  331. for (i = 0; i < chip->mixer.dest_stream_ins; i++)
  332. lola_codec_write(chip, chip->mixer.nid,
  333. LOLA_VERB_SET_DESTINATION_GAIN,
  334. i, 0);
  335. for (i = 0; i < chip->mixer.dest_phys_outs; i++)
  336. lola_codec_write(chip, chip->mixer.nid,
  337. LOLA_VERB_SET_DESTINATION_GAIN,
  338. chip->mixer.dest_phys_out_ofs + i, 0);
  339. lola_codec_flush(chip);
  340. }
  341. }
  342. /*
  343. */
  344. static int set_analog_volume(struct lola *chip, int dir,
  345. unsigned int idx, unsigned int val,
  346. bool external_call)
  347. {
  348. struct lola_pin *pin;
  349. int err;
  350. if (idx >= chip->pin[dir].num_pins)
  351. return -EINVAL;
  352. pin = &chip->pin[dir].pins[idx];
  353. if (!pin->is_analog || pin->amp_num_steps <= val)
  354. return -EINVAL;
  355. if (external_call && pin->cur_gain_step == val)
  356. return 0;
  357. if (external_call)
  358. lola_codec_flush(chip);
  359. dev_dbg(chip->card->dev,
  360. "set_analog_volume (dir=%d idx=%d, volume=%d)\n",
  361. dir, idx, val);
  362. err = lola_codec_write(chip, pin->nid,
  363. LOLA_VERB_SET_AMP_GAIN_MUTE, val, 0);
  364. if (err < 0)
  365. return err;
  366. if (external_call)
  367. pin->cur_gain_step = val;
  368. return 0;
  369. }
  370. int lola_set_src_config(struct lola *chip, unsigned int src_mask, bool update)
  371. {
  372. int ret = 0;
  373. int success = 0;
  374. int n, err;
  375. /* SRC can be activated and the dwInputSRCMask is valid? */
  376. if ((chip->input_src_caps_mask & src_mask) != src_mask)
  377. return -EINVAL;
  378. /* handle all even Inputs - SRC is a stereo setting !!! */
  379. for (n = 0; n < chip->pin[CAPT].num_pins; n += 2) {
  380. unsigned int mask = 3U << n; /* handle the stereo case */
  381. unsigned int new_src, src_state;
  382. if (!(chip->input_src_caps_mask & mask))
  383. continue;
  384. /* if one IO needs SRC, both stereo IO will get SRC */
  385. new_src = (src_mask & mask) != 0;
  386. if (update) {
  387. src_state = (chip->input_src_mask & mask) != 0;
  388. if (src_state == new_src)
  389. continue; /* nothing to change for this IO */
  390. }
  391. err = lola_codec_write(chip, chip->pcm[CAPT].streams[n].nid,
  392. LOLA_VERB_SET_SRC, new_src, 0);
  393. if (!err)
  394. success++;
  395. else
  396. ret = err;
  397. }
  398. if (success)
  399. ret = lola_codec_flush(chip);
  400. if (!ret)
  401. chip->input_src_mask = src_mask;
  402. return ret;
  403. }
  404. /*
  405. */
  406. static int init_mixer_values(struct lola *chip)
  407. {
  408. int i;
  409. /* all sample rate converters on */
  410. lola_set_src_config(chip, (1 << chip->pin[CAPT].num_pins) - 1, false);
  411. /* clear all mixer matrix settings */
  412. memset_io(chip->mixer.array, 0, sizeof(*chip->mixer.array));
  413. /* inform firmware about all updated matrix columns - capture part */
  414. for (i = 0; i < chip->mixer.dest_stream_ins; i++)
  415. lola_codec_write(chip, chip->mixer.nid,
  416. LOLA_VERB_SET_DESTINATION_GAIN,
  417. i, 0);
  418. /* inform firmware about all updated matrix columns - output part */
  419. for (i = 0; i < chip->mixer.dest_phys_outs; i++)
  420. lola_codec_write(chip, chip->mixer.nid,
  421. LOLA_VERB_SET_DESTINATION_GAIN,
  422. chip->mixer.dest_phys_out_ofs + i, 0);
  423. /* set all digital input source (master) gains to 0dB */
  424. for (i = 0; i < chip->mixer.src_phys_ins; i++)
  425. lola_mixer_set_src_gain(chip, i, 336, true); /* 0dB */
  426. /* set all digital playback source (master) gains to 0dB */
  427. for (i = 0; i < chip->mixer.src_stream_outs; i++)
  428. lola_mixer_set_src_gain(chip,
  429. i + chip->mixer.src_stream_out_ofs,
  430. 336, true); /* 0dB */
  431. /* set gain value 0dB diagonally in matrix - part INPUT -> CAPTURE */
  432. for (i = 0; i < chip->mixer.dest_stream_ins; i++) {
  433. int src = i % chip->mixer.src_phys_ins;
  434. lola_mixer_set_mapping_gain(chip, src, i, 336, true);
  435. }
  436. /* set gain value 0dB diagonally in matrix , part PLAYBACK -> OUTPUT
  437. * (LoLa280 : playback channel 0,2,4,6 linked to output channel 0)
  438. * (LoLa280 : playback channel 1,3,5,7 linked to output channel 1)
  439. */
  440. for (i = 0; i < chip->mixer.src_stream_outs; i++) {
  441. int src = chip->mixer.src_stream_out_ofs + i;
  442. int dst = chip->mixer.dest_phys_out_ofs +
  443. i % chip->mixer.dest_phys_outs;
  444. lola_mixer_set_mapping_gain(chip, src, dst, 336, true);
  445. }
  446. return 0;
  447. }
  448. /*
  449. * analog mixer control element
  450. */
  451. static int lola_analog_vol_info(struct snd_kcontrol *kcontrol,
  452. struct snd_ctl_elem_info *uinfo)
  453. {
  454. struct lola *chip = snd_kcontrol_chip(kcontrol);
  455. int dir = kcontrol->private_value;
  456. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  457. uinfo->count = chip->pin[dir].num_pins;
  458. uinfo->value.integer.min = 0;
  459. uinfo->value.integer.max = chip->pin[dir].pins[0].amp_num_steps;
  460. return 0;
  461. }
  462. static int lola_analog_vol_get(struct snd_kcontrol *kcontrol,
  463. struct snd_ctl_elem_value *ucontrol)
  464. {
  465. struct lola *chip = snd_kcontrol_chip(kcontrol);
  466. int dir = kcontrol->private_value;
  467. int i;
  468. for (i = 0; i < chip->pin[dir].num_pins; i++)
  469. ucontrol->value.integer.value[i] =
  470. chip->pin[dir].pins[i].cur_gain_step;
  471. return 0;
  472. }
  473. static int lola_analog_vol_put(struct snd_kcontrol *kcontrol,
  474. struct snd_ctl_elem_value *ucontrol)
  475. {
  476. struct lola *chip = snd_kcontrol_chip(kcontrol);
  477. int dir = kcontrol->private_value;
  478. int i, err;
  479. for (i = 0; i < chip->pin[dir].num_pins; i++) {
  480. err = set_analog_volume(chip, dir, i,
  481. ucontrol->value.integer.value[i],
  482. true);
  483. if (err < 0)
  484. return err;
  485. }
  486. return 0;
  487. }
  488. static int lola_analog_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
  489. unsigned int size, unsigned int __user *tlv)
  490. {
  491. struct lola *chip = snd_kcontrol_chip(kcontrol);
  492. int dir = kcontrol->private_value;
  493. unsigned int val1, val2;
  494. struct lola_pin *pin;
  495. if (size < 4 * sizeof(unsigned int))
  496. return -ENOMEM;
  497. pin = &chip->pin[dir].pins[0];
  498. val2 = pin->amp_step_size * 25;
  499. val1 = -1 * (int)pin->amp_offset * (int)val2;
  500. #ifdef TLV_DB_SCALE_MUTE
  501. val2 |= TLV_DB_SCALE_MUTE;
  502. #endif
  503. if (put_user(SNDRV_CTL_TLVT_DB_SCALE, tlv))
  504. return -EFAULT;
  505. if (put_user(2 * sizeof(unsigned int), tlv + 1))
  506. return -EFAULT;
  507. if (put_user(val1, tlv + 2))
  508. return -EFAULT;
  509. if (put_user(val2, tlv + 3))
  510. return -EFAULT;
  511. return 0;
  512. }
  513. static struct snd_kcontrol_new lola_analog_mixer = {
  514. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  515. .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
  516. SNDRV_CTL_ELEM_ACCESS_TLV_READ |
  517. SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK),
  518. .info = lola_analog_vol_info,
  519. .get = lola_analog_vol_get,
  520. .put = lola_analog_vol_put,
  521. .tlv.c = lola_analog_vol_tlv,
  522. };
  523. static int create_analog_mixer(struct lola *chip, int dir, char *name)
  524. {
  525. if (!chip->pin[dir].num_pins)
  526. return 0;
  527. /* no analog volumes on digital only adapters */
  528. if (chip->pin[dir].num_pins != chip->pin[dir].num_analog_pins)
  529. return 0;
  530. lola_analog_mixer.name = name;
  531. lola_analog_mixer.private_value = dir;
  532. return snd_ctl_add(chip->card,
  533. snd_ctl_new1(&lola_analog_mixer, chip));
  534. }
  535. /*
  536. * Hardware sample rate converter on digital input
  537. */
  538. static int lola_input_src_info(struct snd_kcontrol *kcontrol,
  539. struct snd_ctl_elem_info *uinfo)
  540. {
  541. struct lola *chip = snd_kcontrol_chip(kcontrol);
  542. uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
  543. uinfo->count = chip->pin[CAPT].num_pins;
  544. uinfo->value.integer.min = 0;
  545. uinfo->value.integer.max = 1;
  546. return 0;
  547. }
  548. static int lola_input_src_get(struct snd_kcontrol *kcontrol,
  549. struct snd_ctl_elem_value *ucontrol)
  550. {
  551. struct lola *chip = snd_kcontrol_chip(kcontrol);
  552. int i;
  553. for (i = 0; i < chip->pin[CAPT].num_pins; i++)
  554. ucontrol->value.integer.value[i] =
  555. !!(chip->input_src_mask & (1 << i));
  556. return 0;
  557. }
  558. static int lola_input_src_put(struct snd_kcontrol *kcontrol,
  559. struct snd_ctl_elem_value *ucontrol)
  560. {
  561. struct lola *chip = snd_kcontrol_chip(kcontrol);
  562. int i;
  563. unsigned int mask;
  564. mask = 0;
  565. for (i = 0; i < chip->pin[CAPT].num_pins; i++)
  566. if (ucontrol->value.integer.value[i])
  567. mask |= 1 << i;
  568. return lola_set_src_config(chip, mask, true);
  569. }
  570. static const struct snd_kcontrol_new lola_input_src_mixer = {
  571. .name = "Digital SRC Capture Switch",
  572. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  573. .info = lola_input_src_info,
  574. .get = lola_input_src_get,
  575. .put = lola_input_src_put,
  576. };
  577. /*
  578. * Lola16161 or Lola881 can have Hardware sample rate converters
  579. * on its digital input pins
  580. */
  581. static int create_input_src_mixer(struct lola *chip)
  582. {
  583. if (!chip->input_src_caps_mask)
  584. return 0;
  585. return snd_ctl_add(chip->card,
  586. snd_ctl_new1(&lola_input_src_mixer, chip));
  587. }
  588. /*
  589. * src gain mixer
  590. */
  591. static int lola_src_gain_info(struct snd_kcontrol *kcontrol,
  592. struct snd_ctl_elem_info *uinfo)
  593. {
  594. unsigned int count = (kcontrol->private_value >> 8) & 0xff;
  595. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  596. uinfo->count = count;
  597. uinfo->value.integer.min = 0;
  598. uinfo->value.integer.max = 409;
  599. return 0;
  600. }
  601. static int lola_src_gain_get(struct snd_kcontrol *kcontrol,
  602. struct snd_ctl_elem_value *ucontrol)
  603. {
  604. struct lola *chip = snd_kcontrol_chip(kcontrol);
  605. unsigned int ofs = kcontrol->private_value & 0xff;
  606. unsigned int count = (kcontrol->private_value >> 8) & 0xff;
  607. unsigned int mask, i;
  608. mask = readl(&chip->mixer.array->src_gain_enable);
  609. for (i = 0; i < count; i++) {
  610. unsigned int idx = ofs + i;
  611. unsigned short val;
  612. if (!(chip->mixer.src_mask & (1 << idx)))
  613. return -EINVAL;
  614. if (mask & (1 << idx))
  615. val = readw(&chip->mixer.array->src_gain[idx]) + 1;
  616. else
  617. val = 0;
  618. ucontrol->value.integer.value[i] = val;
  619. }
  620. return 0;
  621. }
  622. static int lola_src_gain_put(struct snd_kcontrol *kcontrol,
  623. struct snd_ctl_elem_value *ucontrol)
  624. {
  625. struct lola *chip = snd_kcontrol_chip(kcontrol);
  626. unsigned int ofs = kcontrol->private_value & 0xff;
  627. unsigned int count = (kcontrol->private_value >> 8) & 0xff;
  628. int i, err;
  629. for (i = 0; i < count; i++) {
  630. unsigned int idx = ofs + i;
  631. unsigned short val = ucontrol->value.integer.value[i];
  632. if (val)
  633. val--;
  634. err = lola_mixer_set_src_gain(chip, idx, val, !!val);
  635. if (err < 0)
  636. return err;
  637. }
  638. return 0;
  639. }
  640. /* raw value: 0 = -84dB, 336 = 0dB, 408=18dB, incremented 1 for mute */
  641. static const DECLARE_TLV_DB_SCALE(lola_src_gain_tlv, -8425, 25, 1);
  642. static struct snd_kcontrol_new lola_src_gain_mixer = {
  643. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  644. .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
  645. SNDRV_CTL_ELEM_ACCESS_TLV_READ),
  646. .info = lola_src_gain_info,
  647. .get = lola_src_gain_get,
  648. .put = lola_src_gain_put,
  649. .tlv.p = lola_src_gain_tlv,
  650. };
  651. static int create_src_gain_mixer(struct lola *chip,
  652. int num, int ofs, char *name)
  653. {
  654. lola_src_gain_mixer.name = name;
  655. lola_src_gain_mixer.private_value = ofs + (num << 8);
  656. return snd_ctl_add(chip->card,
  657. snd_ctl_new1(&lola_src_gain_mixer, chip));
  658. }
  659. #if 0 /* not used */
  660. /*
  661. * destination gain (matrix-like) mixer
  662. */
  663. static int lola_dest_gain_info(struct snd_kcontrol *kcontrol,
  664. struct snd_ctl_elem_info *uinfo)
  665. {
  666. unsigned int src_num = (kcontrol->private_value >> 8) & 0xff;
  667. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  668. uinfo->count = src_num;
  669. uinfo->value.integer.min = 0;
  670. uinfo->value.integer.max = 433;
  671. return 0;
  672. }
  673. static int lola_dest_gain_get(struct snd_kcontrol *kcontrol,
  674. struct snd_ctl_elem_value *ucontrol)
  675. {
  676. struct lola *chip = snd_kcontrol_chip(kcontrol);
  677. unsigned int src_ofs = kcontrol->private_value & 0xff;
  678. unsigned int src_num = (kcontrol->private_value >> 8) & 0xff;
  679. unsigned int dst_ofs = (kcontrol->private_value >> 16) & 0xff;
  680. unsigned int dst, mask, i;
  681. dst = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + dst_ofs;
  682. mask = readl(&chip->mixer.array->dest_mix_gain_enable[dst]);
  683. for (i = 0; i < src_num; i++) {
  684. unsigned int src = src_ofs + i;
  685. unsigned short val;
  686. if (!(chip->mixer.src_mask & (1 << src)))
  687. return -EINVAL;
  688. if (mask & (1 << dst))
  689. val = readw(&chip->mixer.array->dest_mix_gain[dst][src]) + 1;
  690. else
  691. val = 0;
  692. ucontrol->value.integer.value[i] = val;
  693. }
  694. return 0;
  695. }
  696. static int lola_dest_gain_put(struct snd_kcontrol *kcontrol,
  697. struct snd_ctl_elem_value *ucontrol)
  698. {
  699. struct lola *chip = snd_kcontrol_chip(kcontrol);
  700. unsigned int src_ofs = kcontrol->private_value & 0xff;
  701. unsigned int src_num = (kcontrol->private_value >> 8) & 0xff;
  702. unsigned int dst_ofs = (kcontrol->private_value >> 16) & 0xff;
  703. unsigned int dst, mask;
  704. unsigned short gains[MAX_STREAM_COUNT];
  705. int i, num;
  706. mask = 0;
  707. num = 0;
  708. for (i = 0; i < src_num; i++) {
  709. unsigned short val = ucontrol->value.integer.value[i];
  710. if (val) {
  711. gains[num++] = val - 1;
  712. mask |= 1 << i;
  713. }
  714. }
  715. mask <<= src_ofs;
  716. dst = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + dst_ofs;
  717. return lola_mixer_set_dest_gains(chip, dst, mask, gains);
  718. }
  719. static const DECLARE_TLV_DB_SCALE(lola_dest_gain_tlv, -8425, 25, 1);
  720. static struct snd_kcontrol_new lola_dest_gain_mixer = {
  721. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  722. .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
  723. SNDRV_CTL_ELEM_ACCESS_TLV_READ),
  724. .info = lola_dest_gain_info,
  725. .get = lola_dest_gain_get,
  726. .put = lola_dest_gain_put,
  727. .tlv.p = lola_dest_gain_tlv,
  728. };
  729. static int create_dest_gain_mixer(struct lola *chip,
  730. int src_num, int src_ofs,
  731. int num, int ofs, char *name)
  732. {
  733. lola_dest_gain_mixer.count = num;
  734. lola_dest_gain_mixer.name = name;
  735. lola_dest_gain_mixer.private_value =
  736. src_ofs + (src_num << 8) + (ofs << 16) + (num << 24);
  737. return snd_ctl_add(chip->card,
  738. snd_ctl_new1(&lola_dest_gain_mixer, chip));
  739. }
  740. #endif /* not used */
  741. /*
  742. */
  743. int lola_create_mixer(struct lola *chip)
  744. {
  745. int err;
  746. err = create_analog_mixer(chip, PLAY, "Analog Playback Volume");
  747. if (err < 0)
  748. return err;
  749. err = create_analog_mixer(chip, CAPT, "Analog Capture Volume");
  750. if (err < 0)
  751. return err;
  752. err = create_input_src_mixer(chip);
  753. if (err < 0)
  754. return err;
  755. err = create_src_gain_mixer(chip, chip->mixer.src_phys_ins, 0,
  756. "Digital Capture Volume");
  757. if (err < 0)
  758. return err;
  759. err = create_src_gain_mixer(chip, chip->mixer.src_stream_outs,
  760. chip->mixer.src_stream_out_ofs,
  761. "Digital Playback Volume");
  762. if (err < 0)
  763. return err;
  764. #if 0
  765. /* FIXME: buggy mixer matrix handling */
  766. err = create_dest_gain_mixer(chip,
  767. chip->mixer.src_phys_ins, 0,
  768. chip->mixer.dest_stream_ins, 0,
  769. "Line Capture Volume");
  770. if (err < 0)
  771. return err;
  772. err = create_dest_gain_mixer(chip,
  773. chip->mixer.src_stream_outs,
  774. chip->mixer.src_stream_out_ofs,
  775. chip->mixer.dest_stream_ins, 0,
  776. "Stream-Loopback Capture Volume");
  777. if (err < 0)
  778. return err;
  779. err = create_dest_gain_mixer(chip,
  780. chip->mixer.src_phys_ins, 0,
  781. chip->mixer.dest_phys_outs,
  782. chip->mixer.dest_phys_out_ofs,
  783. "Line-Loopback Playback Volume");
  784. if (err < 0)
  785. return err;
  786. err = create_dest_gain_mixer(chip,
  787. chip->mixer.src_stream_outs,
  788. chip->mixer.src_stream_out_ofs,
  789. chip->mixer.dest_phys_outs,
  790. chip->mixer.dest_phys_out_ofs,
  791. "Stream Playback Volume");
  792. if (err < 0)
  793. return err;
  794. #endif /* FIXME */
  795. return init_mixer_values(chip);
  796. }