awacs.c 26 KB

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