awacs.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903
  1. /*
  2. * PMac AWACS lowlevel functions
  3. *
  4. * Copyright (c) by Takashi Iwai <tiwai@suse.de>
  5. * code based on dmasound.c.
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20. */
  21. #include <sound/driver.h>
  22. #include <asm/io.h>
  23. #include <asm/nvram.h>
  24. #include <linux/init.h>
  25. #include <linux/delay.h>
  26. #include <linux/slab.h>
  27. #include <sound/core.h>
  28. #include "pmac.h"
  29. #ifdef CONFIG_ADB_CUDA
  30. #define PMAC_AMP_AVAIL
  31. #endif
  32. #ifdef PMAC_AMP_AVAIL
  33. typedef struct awacs_amp {
  34. unsigned char amp_master;
  35. unsigned char amp_vol[2][2];
  36. unsigned char amp_tone[2];
  37. } awacs_amp_t;
  38. #define CHECK_CUDA_AMP() (sys_ctrler == SYS_CTRLER_CUDA)
  39. #endif /* PMAC_AMP_AVAIL */
  40. static void snd_pmac_screamer_wait(pmac_t *chip)
  41. {
  42. long timeout = 2000;
  43. while (!(in_le32(&chip->awacs->codec_stat) & MASK_VALID)) {
  44. mdelay(1);
  45. if (! --timeout) {
  46. snd_printd("snd_pmac_screamer_wait timeout\n");
  47. break;
  48. }
  49. }
  50. }
  51. /*
  52. * write AWACS register
  53. */
  54. static void
  55. snd_pmac_awacs_write(pmac_t *chip, int val)
  56. {
  57. long timeout = 5000000;
  58. if (chip->model == PMAC_SCREAMER)
  59. snd_pmac_screamer_wait(chip);
  60. out_le32(&chip->awacs->codec_ctrl, val | (chip->subframe << 22));
  61. while (in_le32(&chip->awacs->codec_ctrl) & MASK_NEWECMD) {
  62. if (! --timeout) {
  63. snd_printd("snd_pmac_awacs_write timeout\n");
  64. break;
  65. }
  66. }
  67. }
  68. static void
  69. snd_pmac_awacs_write_reg(pmac_t *chip, int reg, int val)
  70. {
  71. snd_pmac_awacs_write(chip, val | (reg << 12));
  72. chip->awacs_reg[reg] = val;
  73. }
  74. static void
  75. snd_pmac_awacs_write_noreg(pmac_t *chip, int reg, int val)
  76. {
  77. snd_pmac_awacs_write(chip, val | (reg << 12));
  78. }
  79. #ifdef CONFIG_PM
  80. /* Recalibrate chip */
  81. static void screamer_recalibrate(pmac_t *chip)
  82. {
  83. if (chip->model != PMAC_SCREAMER)
  84. return;
  85. /* Sorry for the horrible delays... I hope to get that improved
  86. * by making the whole PM process asynchronous in a future version
  87. */
  88. snd_pmac_awacs_write_noreg(chip, 1, chip->awacs_reg[1]);
  89. if (chip->manufacturer == 0x1)
  90. /* delay for broken crystal part */
  91. msleep(750);
  92. snd_pmac_awacs_write_noreg(chip, 1,
  93. chip->awacs_reg[1] | MASK_RECALIBRATE | MASK_CMUTE | MASK_AMUTE);
  94. snd_pmac_awacs_write_noreg(chip, 1, chip->awacs_reg[1]);
  95. snd_pmac_awacs_write_noreg(chip, 6, chip->awacs_reg[6]);
  96. }
  97. #else
  98. #define screamer_recalibrate(chip) /* NOP */
  99. #endif
  100. /*
  101. * additional callback to set the pcm format
  102. */
  103. static void snd_pmac_awacs_set_format(pmac_t *chip)
  104. {
  105. chip->awacs_reg[1] &= ~MASK_SAMPLERATE;
  106. chip->awacs_reg[1] |= chip->rate_index << 3;
  107. snd_pmac_awacs_write_reg(chip, 1, chip->awacs_reg[1]);
  108. }
  109. /*
  110. * AWACS volume callbacks
  111. */
  112. /*
  113. * volumes: 0-15 stereo
  114. */
  115. static int snd_pmac_awacs_info_volume(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
  116. {
  117. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  118. uinfo->count = 2;
  119. uinfo->value.integer.min = 0;
  120. uinfo->value.integer.max = 15;
  121. return 0;
  122. }
  123. static int snd_pmac_awacs_get_volume(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
  124. {
  125. pmac_t *chip = snd_kcontrol_chip(kcontrol);
  126. int reg = kcontrol->private_value & 0xff;
  127. int lshift = (kcontrol->private_value >> 8) & 0xff;
  128. int inverted = (kcontrol->private_value >> 16) & 1;
  129. unsigned long flags;
  130. int vol[2];
  131. spin_lock_irqsave(&chip->reg_lock, flags);
  132. vol[0] = (chip->awacs_reg[reg] >> lshift) & 0xf;
  133. vol[1] = chip->awacs_reg[reg] & 0xf;
  134. spin_unlock_irqrestore(&chip->reg_lock, flags);
  135. if (inverted) {
  136. vol[0] = 0x0f - vol[0];
  137. vol[1] = 0x0f - vol[1];
  138. }
  139. ucontrol->value.integer.value[0] = vol[0];
  140. ucontrol->value.integer.value[1] = vol[1];
  141. return 0;
  142. }
  143. static int snd_pmac_awacs_put_volume(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
  144. {
  145. pmac_t *chip = snd_kcontrol_chip(kcontrol);
  146. int reg = kcontrol->private_value & 0xff;
  147. int lshift = (kcontrol->private_value >> 8) & 0xff;
  148. int inverted = (kcontrol->private_value >> 16) & 1;
  149. int val, oldval;
  150. unsigned long flags;
  151. int vol[2];
  152. vol[0] = ucontrol->value.integer.value[0];
  153. vol[1] = ucontrol->value.integer.value[1];
  154. if (inverted) {
  155. vol[0] = 0x0f - vol[0];
  156. vol[1] = 0x0f - vol[1];
  157. }
  158. vol[0] &= 0x0f;
  159. vol[1] &= 0x0f;
  160. spin_lock_irqsave(&chip->reg_lock, flags);
  161. oldval = chip->awacs_reg[reg];
  162. val = oldval & ~(0xf | (0xf << lshift));
  163. val |= vol[0] << lshift;
  164. val |= vol[1];
  165. if (oldval != val)
  166. snd_pmac_awacs_write_reg(chip, reg, val);
  167. spin_unlock_irqrestore(&chip->reg_lock, flags);
  168. return oldval != reg;
  169. }
  170. #define AWACS_VOLUME(xname, xreg, xshift, xinverted) \
  171. { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
  172. .info = snd_pmac_awacs_info_volume, \
  173. .get = snd_pmac_awacs_get_volume, \
  174. .put = snd_pmac_awacs_put_volume, \
  175. .private_value = (xreg) | ((xshift) << 8) | ((xinverted) << 16) }
  176. /*
  177. * mute master/ogain for AWACS: mono
  178. */
  179. static int snd_pmac_awacs_get_switch(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
  180. {
  181. pmac_t *chip = snd_kcontrol_chip(kcontrol);
  182. int reg = kcontrol->private_value & 0xff;
  183. int shift = (kcontrol->private_value >> 8) & 0xff;
  184. int invert = (kcontrol->private_value >> 16) & 1;
  185. int val;
  186. unsigned long flags;
  187. spin_lock_irqsave(&chip->reg_lock, flags);
  188. val = (chip->awacs_reg[reg] >> shift) & 1;
  189. spin_unlock_irqrestore(&chip->reg_lock, flags);
  190. if (invert)
  191. val = 1 - val;
  192. ucontrol->value.integer.value[0] = val;
  193. return 0;
  194. }
  195. static int snd_pmac_awacs_put_switch(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
  196. {
  197. pmac_t *chip = snd_kcontrol_chip(kcontrol);
  198. int reg = kcontrol->private_value & 0xff;
  199. int shift = (kcontrol->private_value >> 8) & 0xff;
  200. int invert = (kcontrol->private_value >> 16) & 1;
  201. int mask = 1 << shift;
  202. int val, changed;
  203. unsigned long flags;
  204. spin_lock_irqsave(&chip->reg_lock, flags);
  205. val = chip->awacs_reg[reg] & ~mask;
  206. if (ucontrol->value.integer.value[0] != invert)
  207. val |= mask;
  208. changed = chip->awacs_reg[reg] != val;
  209. if (changed)
  210. snd_pmac_awacs_write_reg(chip, reg, val);
  211. spin_unlock_irqrestore(&chip->reg_lock, flags);
  212. return changed;
  213. }
  214. #define AWACS_SWITCH(xname, xreg, xshift, xinvert) \
  215. { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
  216. .info = snd_pmac_boolean_mono_info, \
  217. .get = snd_pmac_awacs_get_switch, \
  218. .put = snd_pmac_awacs_put_switch, \
  219. .private_value = (xreg) | ((xshift) << 8) | ((xinvert) << 16) }
  220. #ifdef PMAC_AMP_AVAIL
  221. /*
  222. * controls for perch/whisper extension cards, e.g. G3 desktop
  223. *
  224. * TDA7433 connected via i2c address 0x45 (= 0x8a),
  225. * accessed through cuda
  226. */
  227. static void awacs_set_cuda(int reg, int val)
  228. {
  229. struct adb_request req;
  230. cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC, 0x8a, reg, val);
  231. while (! req.complete)
  232. cuda_poll();
  233. }
  234. /*
  235. * level = 0 - 14, 7 = 0 dB
  236. */
  237. static void awacs_amp_set_tone(awacs_amp_t *amp, int bass, int treble)
  238. {
  239. amp->amp_tone[0] = bass;
  240. amp->amp_tone[1] = treble;
  241. if (bass > 7)
  242. bass = (14 - bass) + 8;
  243. if (treble > 7)
  244. treble = (14 - treble) + 8;
  245. awacs_set_cuda(2, (bass << 4) | treble);
  246. }
  247. /*
  248. * vol = 0 - 31 (attenuation), 32 = mute bit, stereo
  249. */
  250. static int awacs_amp_set_vol(awacs_amp_t *amp, int index, int lvol, int rvol, int do_check)
  251. {
  252. if (do_check && amp->amp_vol[index][0] == lvol &&
  253. amp->amp_vol[index][1] == rvol)
  254. return 0;
  255. awacs_set_cuda(3 + index, lvol);
  256. awacs_set_cuda(5 + index, rvol);
  257. amp->amp_vol[index][0] = lvol;
  258. amp->amp_vol[index][1] = rvol;
  259. return 1;
  260. }
  261. /*
  262. * 0 = -79 dB, 79 = 0 dB, 99 = +20 dB
  263. */
  264. static void awacs_amp_set_master(awacs_amp_t *amp, int vol)
  265. {
  266. amp->amp_master = vol;
  267. if (vol <= 79)
  268. vol = 32 + (79 - vol);
  269. else
  270. vol = 32 - (vol - 79);
  271. awacs_set_cuda(1, vol);
  272. }
  273. static void awacs_amp_free(pmac_t *chip)
  274. {
  275. awacs_amp_t *amp = chip->mixer_data;
  276. snd_assert(amp, return);
  277. kfree(amp);
  278. chip->mixer_data = NULL;
  279. chip->mixer_free = NULL;
  280. }
  281. /*
  282. * mixer controls
  283. */
  284. static int snd_pmac_awacs_info_volume_amp(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
  285. {
  286. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  287. uinfo->count = 2;
  288. uinfo->value.integer.min = 0;
  289. uinfo->value.integer.max = 31;
  290. return 0;
  291. }
  292. static int snd_pmac_awacs_get_volume_amp(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
  293. {
  294. pmac_t *chip = snd_kcontrol_chip(kcontrol);
  295. int index = kcontrol->private_value;
  296. awacs_amp_t *amp = chip->mixer_data;
  297. snd_assert(amp, return -EINVAL);
  298. snd_assert(index >= 0 && index <= 1, return -EINVAL);
  299. ucontrol->value.integer.value[0] = 31 - (amp->amp_vol[index][0] & 31);
  300. ucontrol->value.integer.value[1] = 31 - (amp->amp_vol[index][1] & 31);
  301. return 0;
  302. }
  303. static int snd_pmac_awacs_put_volume_amp(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
  304. {
  305. pmac_t *chip = snd_kcontrol_chip(kcontrol);
  306. int index = kcontrol->private_value;
  307. int vol[2];
  308. awacs_amp_t *amp = chip->mixer_data;
  309. snd_assert(amp, return -EINVAL);
  310. snd_assert(index >= 0 && index <= 1, return -EINVAL);
  311. vol[0] = (31 - (ucontrol->value.integer.value[0] & 31)) | (amp->amp_vol[index][0] & 32);
  312. vol[1] = (31 - (ucontrol->value.integer.value[1] & 31)) | (amp->amp_vol[index][1] & 32);
  313. return awacs_amp_set_vol(amp, index, vol[0], vol[1], 1);
  314. }
  315. static int snd_pmac_awacs_get_switch_amp(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
  316. {
  317. pmac_t *chip = snd_kcontrol_chip(kcontrol);
  318. int index = kcontrol->private_value;
  319. awacs_amp_t *amp = chip->mixer_data;
  320. snd_assert(amp, return -EINVAL);
  321. snd_assert(index >= 0 && index <= 1, return -EINVAL);
  322. ucontrol->value.integer.value[0] = (amp->amp_vol[index][0] & 32) ? 0 : 1;
  323. ucontrol->value.integer.value[1] = (amp->amp_vol[index][1] & 32) ? 0 : 1;
  324. return 0;
  325. }
  326. static int snd_pmac_awacs_put_switch_amp(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
  327. {
  328. pmac_t *chip = snd_kcontrol_chip(kcontrol);
  329. int index = kcontrol->private_value;
  330. int vol[2];
  331. awacs_amp_t *amp = chip->mixer_data;
  332. snd_assert(amp, return -EINVAL);
  333. snd_assert(index >= 0 && index <= 1, return -EINVAL);
  334. vol[0] = (ucontrol->value.integer.value[0] ? 0 : 32) | (amp->amp_vol[index][0] & 31);
  335. vol[1] = (ucontrol->value.integer.value[1] ? 0 : 32) | (amp->amp_vol[index][1] & 31);
  336. return awacs_amp_set_vol(amp, index, vol[0], vol[1], 1);
  337. }
  338. static int snd_pmac_awacs_info_tone_amp(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
  339. {
  340. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  341. uinfo->count = 1;
  342. uinfo->value.integer.min = 0;
  343. uinfo->value.integer.max = 14;
  344. return 0;
  345. }
  346. static int snd_pmac_awacs_get_tone_amp(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
  347. {
  348. pmac_t *chip = snd_kcontrol_chip(kcontrol);
  349. int index = kcontrol->private_value;
  350. awacs_amp_t *amp = chip->mixer_data;
  351. snd_assert(amp, return -EINVAL);
  352. snd_assert(index >= 0 && index <= 1, return -EINVAL);
  353. ucontrol->value.integer.value[0] = amp->amp_tone[index];
  354. return 0;
  355. }
  356. static int snd_pmac_awacs_put_tone_amp(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
  357. {
  358. pmac_t *chip = snd_kcontrol_chip(kcontrol);
  359. int index = kcontrol->private_value;
  360. awacs_amp_t *amp = chip->mixer_data;
  361. snd_assert(amp, return -EINVAL);
  362. snd_assert(index >= 0 && index <= 1, return -EINVAL);
  363. if (ucontrol->value.integer.value[0] != amp->amp_tone[index]) {
  364. amp->amp_tone[index] = ucontrol->value.integer.value[0];
  365. awacs_amp_set_tone(amp, amp->amp_tone[0], amp->amp_tone[1]);
  366. return 1;
  367. }
  368. return 0;
  369. }
  370. static int snd_pmac_awacs_info_master_amp(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
  371. {
  372. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  373. uinfo->count = 1;
  374. uinfo->value.integer.min = 0;
  375. uinfo->value.integer.max = 99;
  376. return 0;
  377. }
  378. static int snd_pmac_awacs_get_master_amp(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
  379. {
  380. pmac_t *chip = snd_kcontrol_chip(kcontrol);
  381. awacs_amp_t *amp = chip->mixer_data;
  382. snd_assert(amp, return -EINVAL);
  383. ucontrol->value.integer.value[0] = amp->amp_master;
  384. return 0;
  385. }
  386. static int snd_pmac_awacs_put_master_amp(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
  387. {
  388. pmac_t *chip = snd_kcontrol_chip(kcontrol);
  389. awacs_amp_t *amp = chip->mixer_data;
  390. snd_assert(amp, return -EINVAL);
  391. if (ucontrol->value.integer.value[0] != amp->amp_master) {
  392. amp->amp_master = ucontrol->value.integer.value[0];
  393. awacs_amp_set_master(amp, amp->amp_master);
  394. return 1;
  395. }
  396. return 0;
  397. }
  398. #define AMP_CH_SPK 0
  399. #define AMP_CH_HD 1
  400. static snd_kcontrol_new_t snd_pmac_awacs_amp_vol[] __initdata = {
  401. { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  402. .name = "PC Speaker Playback Volume",
  403. .info = snd_pmac_awacs_info_volume_amp,
  404. .get = snd_pmac_awacs_get_volume_amp,
  405. .put = snd_pmac_awacs_put_volume_amp,
  406. .private_value = AMP_CH_SPK,
  407. },
  408. { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  409. .name = "Headphone Playback Volume",
  410. .info = snd_pmac_awacs_info_volume_amp,
  411. .get = snd_pmac_awacs_get_volume_amp,
  412. .put = snd_pmac_awacs_put_volume_amp,
  413. .private_value = AMP_CH_HD,
  414. },
  415. { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  416. .name = "Tone Control - Bass",
  417. .info = snd_pmac_awacs_info_tone_amp,
  418. .get = snd_pmac_awacs_get_tone_amp,
  419. .put = snd_pmac_awacs_put_tone_amp,
  420. .private_value = 0,
  421. },
  422. { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  423. .name = "Tone Control - Treble",
  424. .info = snd_pmac_awacs_info_tone_amp,
  425. .get = snd_pmac_awacs_get_tone_amp,
  426. .put = snd_pmac_awacs_put_tone_amp,
  427. .private_value = 1,
  428. },
  429. { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  430. .name = "Amp Master Playback Volume",
  431. .info = snd_pmac_awacs_info_master_amp,
  432. .get = snd_pmac_awacs_get_master_amp,
  433. .put = snd_pmac_awacs_put_master_amp,
  434. },
  435. };
  436. static snd_kcontrol_new_t snd_pmac_awacs_amp_hp_sw __initdata = {
  437. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  438. .name = "Headphone Playback Switch",
  439. .info = snd_pmac_boolean_stereo_info,
  440. .get = snd_pmac_awacs_get_switch_amp,
  441. .put = snd_pmac_awacs_put_switch_amp,
  442. .private_value = AMP_CH_HD,
  443. };
  444. static snd_kcontrol_new_t snd_pmac_awacs_amp_spk_sw __initdata = {
  445. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  446. .name = "PC Speaker Playback Switch",
  447. .info = snd_pmac_boolean_stereo_info,
  448. .get = snd_pmac_awacs_get_switch_amp,
  449. .put = snd_pmac_awacs_put_switch_amp,
  450. .private_value = AMP_CH_SPK,
  451. };
  452. #endif /* PMAC_AMP_AVAIL */
  453. /*
  454. * mic boost for screamer
  455. */
  456. static int snd_pmac_screamer_mic_boost_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
  457. {
  458. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  459. uinfo->count = 1;
  460. uinfo->value.integer.min = 0;
  461. uinfo->value.integer.max = 2;
  462. return 0;
  463. }
  464. static int snd_pmac_screamer_mic_boost_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
  465. {
  466. pmac_t *chip = snd_kcontrol_chip(kcontrol);
  467. int val;
  468. unsigned long flags;
  469. spin_lock_irqsave(&chip->reg_lock, flags);
  470. if (chip->awacs_reg[6] & MASK_MIC_BOOST)
  471. val = 2;
  472. else if (chip->awacs_reg[0] & MASK_GAINLINE)
  473. val = 1;
  474. else
  475. val = 0;
  476. spin_unlock_irqrestore(&chip->reg_lock, flags);
  477. ucontrol->value.integer.value[0] = val;
  478. return 0;
  479. }
  480. static int snd_pmac_screamer_mic_boost_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
  481. {
  482. pmac_t *chip = snd_kcontrol_chip(kcontrol);
  483. int changed = 0;
  484. int val0, val6;
  485. unsigned long flags;
  486. spin_lock_irqsave(&chip->reg_lock, flags);
  487. val0 = chip->awacs_reg[0] & ~MASK_GAINLINE;
  488. val6 = chip->awacs_reg[6] & ~MASK_MIC_BOOST;
  489. if (ucontrol->value.integer.value[0] > 0) {
  490. val0 |= MASK_GAINLINE;
  491. if (ucontrol->value.integer.value[0] > 1)
  492. val6 |= MASK_MIC_BOOST;
  493. }
  494. if (val0 != chip->awacs_reg[0]) {
  495. snd_pmac_awacs_write_reg(chip, 0, val0);
  496. changed = 1;
  497. }
  498. if (val6 != chip->awacs_reg[6]) {
  499. snd_pmac_awacs_write_reg(chip, 6, val6);
  500. changed = 1;
  501. }
  502. spin_unlock_irqrestore(&chip->reg_lock, flags);
  503. return changed;
  504. }
  505. /*
  506. * lists of mixer elements
  507. */
  508. static snd_kcontrol_new_t snd_pmac_awacs_mixers[] __initdata = {
  509. AWACS_VOLUME("Master Playback Volume", 2, 6, 1),
  510. AWACS_SWITCH("Master Capture Switch", 1, SHIFT_LOOPTHRU, 0),
  511. AWACS_VOLUME("Capture Volume", 0, 4, 0),
  512. AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
  513. };
  514. /* FIXME: is this correct order?
  515. * screamer (powerbook G3 pismo) seems to have different bits...
  516. */
  517. static snd_kcontrol_new_t snd_pmac_awacs_mixers2[] __initdata = {
  518. AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_LINE, 0),
  519. AWACS_SWITCH("Mic Capture Switch", 0, SHIFT_MUX_MIC, 0),
  520. };
  521. static snd_kcontrol_new_t snd_pmac_screamer_mixers2[] __initdata = {
  522. AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_MIC, 0),
  523. AWACS_SWITCH("Mic Capture Switch", 0, SHIFT_MUX_LINE, 0),
  524. };
  525. static snd_kcontrol_new_t snd_pmac_awacs_master_sw __initdata =
  526. AWACS_SWITCH("Master Playback Switch", 1, SHIFT_HDMUTE, 1);
  527. static snd_kcontrol_new_t snd_pmac_awacs_mic_boost[] __initdata = {
  528. AWACS_SWITCH("Mic Boost", 0, SHIFT_GAINLINE, 0),
  529. };
  530. static snd_kcontrol_new_t snd_pmac_screamer_mic_boost[] __initdata = {
  531. { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  532. .name = "Mic Boost",
  533. .info = snd_pmac_screamer_mic_boost_info,
  534. .get = snd_pmac_screamer_mic_boost_get,
  535. .put = snd_pmac_screamer_mic_boost_put,
  536. },
  537. };
  538. static snd_kcontrol_new_t snd_pmac_awacs_speaker_vol[] __initdata = {
  539. AWACS_VOLUME("PC Speaker Playback Volume", 4, 6, 1),
  540. };
  541. static snd_kcontrol_new_t snd_pmac_awacs_speaker_sw __initdata =
  542. AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_SPKMUTE, 1);
  543. /*
  544. * add new mixer elements to the card
  545. */
  546. static int build_mixers(pmac_t *chip, int nums, snd_kcontrol_new_t *mixers)
  547. {
  548. int i, err;
  549. for (i = 0; i < nums; i++) {
  550. if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&mixers[i], chip))) < 0)
  551. return err;
  552. }
  553. return 0;
  554. }
  555. /*
  556. * restore all registers
  557. */
  558. static void awacs_restore_all_regs(pmac_t *chip)
  559. {
  560. snd_pmac_awacs_write_noreg(chip, 0, chip->awacs_reg[0]);
  561. snd_pmac_awacs_write_noreg(chip, 1, chip->awacs_reg[1]);
  562. snd_pmac_awacs_write_noreg(chip, 2, chip->awacs_reg[2]);
  563. snd_pmac_awacs_write_noreg(chip, 4, chip->awacs_reg[4]);
  564. if (chip->model == PMAC_SCREAMER) {
  565. snd_pmac_awacs_write_noreg(chip, 5, chip->awacs_reg[5]);
  566. snd_pmac_awacs_write_noreg(chip, 6, chip->awacs_reg[6]);
  567. snd_pmac_awacs_write_noreg(chip, 7, chip->awacs_reg[7]);
  568. }
  569. }
  570. #ifdef CONFIG_PM
  571. static void snd_pmac_awacs_suspend(pmac_t *chip)
  572. {
  573. snd_pmac_awacs_write_noreg(chip, 1, (chip->awacs_reg[1]
  574. | MASK_AMUTE | MASK_CMUTE));
  575. }
  576. static void snd_pmac_awacs_resume(pmac_t *chip)
  577. {
  578. if (machine_is_compatible("PowerBook3,1")
  579. || machine_is_compatible("PowerBook3,2")) {
  580. msleep(100);
  581. snd_pmac_awacs_write_reg(chip, 1,
  582. chip->awacs_reg[1] & ~MASK_PAROUT);
  583. msleep(300);
  584. }
  585. awacs_restore_all_regs(chip);
  586. if (chip->model == PMAC_SCREAMER) {
  587. /* reset power bits in reg 6 */
  588. mdelay(5);
  589. snd_pmac_awacs_write_noreg(chip, 6, chip->awacs_reg[6]);
  590. }
  591. screamer_recalibrate(chip);
  592. #ifdef PMAC_AMP_AVAIL
  593. if (chip->mixer_data) {
  594. awacs_amp_t *amp = chip->mixer_data;
  595. awacs_amp_set_vol(amp, 0, amp->amp_vol[0][0], amp->amp_vol[0][1], 0);
  596. awacs_amp_set_vol(amp, 1, amp->amp_vol[1][0], amp->amp_vol[1][1], 0);
  597. awacs_amp_set_tone(amp, amp->amp_tone[0], amp->amp_tone[1]);
  598. awacs_amp_set_master(amp, amp->amp_master);
  599. }
  600. #endif
  601. }
  602. #endif /* CONFIG_PM */
  603. #ifdef PMAC_SUPPORT_AUTOMUTE
  604. /*
  605. * auto-mute stuffs
  606. */
  607. static int snd_pmac_awacs_detect_headphone(pmac_t *chip)
  608. {
  609. return (in_le32(&chip->awacs->codec_stat) & chip->hp_stat_mask) ? 1 : 0;
  610. }
  611. #ifdef PMAC_AMP_AVAIL
  612. static int toggle_amp_mute(awacs_amp_t *amp, int index, int mute)
  613. {
  614. int vol[2];
  615. vol[0] = amp->amp_vol[index][0] & 31;
  616. vol[1] = amp->amp_vol[index][1] & 31;
  617. if (mute) {
  618. vol[0] |= 32;
  619. vol[1] |= 32;
  620. }
  621. return awacs_amp_set_vol(amp, index, vol[0], vol[1], 1);
  622. }
  623. #endif
  624. static void snd_pmac_awacs_update_automute(pmac_t *chip, int do_notify)
  625. {
  626. if (chip->auto_mute) {
  627. #ifdef PMAC_AMP_AVAIL
  628. if (chip->mixer_data) {
  629. awacs_amp_t *amp = chip->mixer_data;
  630. int changed;
  631. if (snd_pmac_awacs_detect_headphone(chip)) {
  632. changed = toggle_amp_mute(amp, AMP_CH_HD, 0);
  633. changed |= toggle_amp_mute(amp, AMP_CH_SPK, 1);
  634. } else {
  635. changed = toggle_amp_mute(amp, AMP_CH_HD, 1);
  636. changed |= toggle_amp_mute(amp, AMP_CH_SPK, 0);
  637. }
  638. if (do_notify && ! changed)
  639. return;
  640. } else
  641. #endif
  642. {
  643. int reg = chip->awacs_reg[1] | (MASK_HDMUTE|MASK_SPKMUTE);
  644. if (snd_pmac_awacs_detect_headphone(chip))
  645. reg &= ~MASK_HDMUTE;
  646. else
  647. reg &= ~MASK_SPKMUTE;
  648. if (do_notify && reg == chip->awacs_reg[1])
  649. return;
  650. snd_pmac_awacs_write_reg(chip, 1, reg);
  651. }
  652. if (do_notify) {
  653. snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
  654. &chip->master_sw_ctl->id);
  655. snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
  656. &chip->speaker_sw_ctl->id);
  657. snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
  658. &chip->hp_detect_ctl->id);
  659. }
  660. }
  661. }
  662. #endif /* PMAC_SUPPORT_AUTOMUTE */
  663. /*
  664. * initialize chip
  665. */
  666. int __init
  667. snd_pmac_awacs_init(pmac_t *chip)
  668. {
  669. int err, vol;
  670. /* looks like MASK_GAINLINE triggers something, so we set here
  671. * as start-up
  672. */
  673. chip->awacs_reg[0] = MASK_MUX_CD | 0xff | MASK_GAINLINE;
  674. chip->awacs_reg[1] = MASK_CMUTE | MASK_AMUTE;
  675. /* FIXME: Only machines with external SRS module need MASK_PAROUT */
  676. if (chip->has_iic || chip->device_id == 0x5 ||
  677. /*chip->_device_id == 0x8 || */
  678. chip->device_id == 0xb)
  679. chip->awacs_reg[1] |= MASK_PAROUT;
  680. /* get default volume from nvram */
  681. // vol = (~nvram_read_byte(0x1308) & 7) << 1;
  682. // vol = ((pmac_xpram_read( 8 ) & 7 ) << 1 );
  683. vol = 0x0f; /* no, on alsa, muted as default */
  684. vol = vol + (vol << 6);
  685. chip->awacs_reg[2] = vol;
  686. chip->awacs_reg[4] = vol;
  687. if (chip->model == PMAC_SCREAMER) {
  688. chip->awacs_reg[5] = vol; /* FIXME: screamer has loopthru vol control */
  689. chip->awacs_reg[6] = MASK_MIC_BOOST; /* FIXME: maybe should be vol << 3 for PCMCIA speaker */
  690. chip->awacs_reg[7] = 0;
  691. }
  692. awacs_restore_all_regs(chip);
  693. chip->manufacturer = (in_le32(&chip->awacs->codec_stat) >> 8) & 0xf;
  694. screamer_recalibrate(chip);
  695. chip->revision = (in_le32(&chip->awacs->codec_stat) >> 12) & 0xf;
  696. #ifdef PMAC_AMP_AVAIL
  697. if (chip->revision == 3 && chip->has_iic && CHECK_CUDA_AMP()) {
  698. awacs_amp_t *amp = kmalloc(sizeof(*amp), GFP_KERNEL);
  699. if (! amp)
  700. return -ENOMEM;
  701. chip->mixer_data = amp;
  702. memset(amp, 0, sizeof(*amp));
  703. chip->mixer_free = awacs_amp_free;
  704. awacs_amp_set_vol(amp, 0, 63, 63, 0); /* mute and zero vol */
  705. awacs_amp_set_vol(amp, 1, 63, 63, 0);
  706. awacs_amp_set_tone(amp, 7, 7); /* 0 dB */
  707. awacs_amp_set_master(amp, 79); /* 0 dB */
  708. }
  709. #endif /* PMAC_AMP_AVAIL */
  710. if (chip->hp_stat_mask == 0) {
  711. /* set headphone-jack detection bit */
  712. switch (chip->model) {
  713. case PMAC_AWACS:
  714. chip->hp_stat_mask = 0x04;
  715. break;
  716. case PMAC_SCREAMER:
  717. switch (chip->device_id) {
  718. case 0x08:
  719. /* 1 = side jack, 2 = front jack */
  720. chip->hp_stat_mask = 0x03;
  721. break;
  722. case 0x00:
  723. case 0x05:
  724. chip->hp_stat_mask = 0x04;
  725. break;
  726. default:
  727. chip->hp_stat_mask = 0x08;
  728. break;
  729. }
  730. break;
  731. default:
  732. snd_BUG();
  733. break;
  734. }
  735. }
  736. /*
  737. * build mixers
  738. */
  739. strcpy(chip->card->mixername, "PowerMac AWACS");
  740. if ((err = build_mixers(chip, ARRAY_SIZE(snd_pmac_awacs_mixers),
  741. snd_pmac_awacs_mixers)) < 0)
  742. return err;
  743. if (chip->model == PMAC_SCREAMER)
  744. err = build_mixers(chip, ARRAY_SIZE(snd_pmac_screamer_mixers2),
  745. snd_pmac_screamer_mixers2);
  746. else
  747. err = build_mixers(chip, ARRAY_SIZE(snd_pmac_awacs_mixers2),
  748. snd_pmac_awacs_mixers2);
  749. if (err < 0)
  750. return err;
  751. chip->master_sw_ctl = snd_ctl_new1(&snd_pmac_awacs_master_sw, chip);
  752. if ((err = snd_ctl_add(chip->card, chip->master_sw_ctl)) < 0)
  753. return err;
  754. #ifdef PMAC_AMP_AVAIL
  755. if (chip->mixer_data) {
  756. /* use amplifier. the signal is connected from route A
  757. * to the amp. the amp has its headphone and speaker
  758. * volumes and mute switches, so we use them instead of
  759. * screamer registers.
  760. * in this case, it seems the route C is not used.
  761. */
  762. if ((err = build_mixers(chip, ARRAY_SIZE(snd_pmac_awacs_amp_vol),
  763. snd_pmac_awacs_amp_vol)) < 0)
  764. return err;
  765. /* overwrite */
  766. chip->master_sw_ctl = snd_ctl_new1(&snd_pmac_awacs_amp_hp_sw, chip);
  767. if ((err = snd_ctl_add(chip->card, chip->master_sw_ctl)) < 0)
  768. return err;
  769. chip->speaker_sw_ctl = snd_ctl_new1(&snd_pmac_awacs_amp_spk_sw, chip);
  770. if ((err = snd_ctl_add(chip->card, chip->speaker_sw_ctl)) < 0)
  771. return err;
  772. } else
  773. #endif /* PMAC_AMP_AVAIL */
  774. {
  775. /* route A = headphone, route C = speaker */
  776. if ((err = build_mixers(chip, ARRAY_SIZE(snd_pmac_awacs_speaker_vol),
  777. snd_pmac_awacs_speaker_vol)) < 0)
  778. return err;
  779. chip->speaker_sw_ctl = snd_ctl_new1(&snd_pmac_awacs_speaker_sw, chip);
  780. if ((err = snd_ctl_add(chip->card, chip->speaker_sw_ctl)) < 0)
  781. return err;
  782. }
  783. if (chip->model == PMAC_SCREAMER) {
  784. if ((err = build_mixers(chip, ARRAY_SIZE(snd_pmac_screamer_mic_boost),
  785. snd_pmac_screamer_mic_boost)) < 0)
  786. return err;
  787. } else {
  788. if ((err = build_mixers(chip, ARRAY_SIZE(snd_pmac_awacs_mic_boost),
  789. snd_pmac_awacs_mic_boost)) < 0)
  790. return err;
  791. }
  792. /*
  793. * set lowlevel callbacks
  794. */
  795. chip->set_format = snd_pmac_awacs_set_format;
  796. #ifdef CONFIG_PM
  797. chip->suspend = snd_pmac_awacs_suspend;
  798. chip->resume = snd_pmac_awacs_resume;
  799. #endif
  800. #ifdef PMAC_SUPPORT_AUTOMUTE
  801. if ((err = snd_pmac_add_automute(chip)) < 0)
  802. return err;
  803. chip->detect_headphone = snd_pmac_awacs_detect_headphone;
  804. chip->update_automute = snd_pmac_awacs_update_automute;
  805. snd_pmac_awacs_update_automute(chip, 0); /* update the status only */
  806. #endif
  807. if (chip->model == PMAC_SCREAMER) {
  808. snd_pmac_awacs_write_noreg(chip, 6, chip->awacs_reg[6]);
  809. snd_pmac_awacs_write_noreg(chip, 0, chip->awacs_reg[0]);
  810. }
  811. return 0;
  812. }