daca.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. /*
  2. * PMac DACA lowlevel functions
  3. *
  4. * Copyright (c) by Takashi Iwai <tiwai@suse.de>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. */
  20. #include <linux/init.h>
  21. #include <linux/i2c.h>
  22. #include <linux/kmod.h>
  23. #include <linux/slab.h>
  24. #include <sound/core.h>
  25. #include "pmac.h"
  26. /* i2c address */
  27. #define DACA_I2C_ADDR 0x4d
  28. /* registers */
  29. #define DACA_REG_SR 0x01
  30. #define DACA_REG_AVOL 0x02
  31. #define DACA_REG_GCFG 0x03
  32. /* maximum volume value */
  33. #define DACA_VOL_MAX 0x38
  34. struct pmac_daca {
  35. struct pmac_keywest i2c;
  36. int left_vol, right_vol;
  37. unsigned int deemphasis : 1;
  38. unsigned int amp_on : 1;
  39. };
  40. /*
  41. * initialize / detect DACA
  42. */
  43. static int daca_init_client(struct pmac_keywest *i2c)
  44. {
  45. unsigned short wdata = 0x00;
  46. /* SR: no swap, 1bit delay, 32-48kHz */
  47. /* GCFG: power amp inverted, DAC on */
  48. if (i2c_smbus_write_byte_data(i2c->client, DACA_REG_SR, 0x08) < 0 ||
  49. i2c_smbus_write_byte_data(i2c->client, DACA_REG_GCFG, 0x05) < 0)
  50. return -EINVAL;
  51. return i2c_smbus_write_block_data(i2c->client, DACA_REG_AVOL,
  52. 2, (unsigned char*)&wdata);
  53. }
  54. /*
  55. * update volume
  56. */
  57. static int daca_set_volume(struct pmac_daca *mix)
  58. {
  59. unsigned char data[2];
  60. if (! mix->i2c.client)
  61. return -ENODEV;
  62. if (mix->left_vol > DACA_VOL_MAX)
  63. data[0] = DACA_VOL_MAX;
  64. else
  65. data[0] = mix->left_vol;
  66. if (mix->right_vol > DACA_VOL_MAX)
  67. data[1] = DACA_VOL_MAX;
  68. else
  69. data[1] = mix->right_vol;
  70. data[1] |= mix->deemphasis ? 0x40 : 0;
  71. if (i2c_smbus_write_block_data(mix->i2c.client, DACA_REG_AVOL,
  72. 2, data) < 0) {
  73. snd_printk(KERN_ERR "failed to set volume \n");
  74. return -EINVAL;
  75. }
  76. return 0;
  77. }
  78. /* deemphasis switch */
  79. #define daca_info_deemphasis snd_ctl_boolean_mono_info
  80. static int daca_get_deemphasis(struct snd_kcontrol *kcontrol,
  81. struct snd_ctl_elem_value *ucontrol)
  82. {
  83. struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
  84. struct pmac_daca *mix;
  85. if (! (mix = chip->mixer_data))
  86. return -ENODEV;
  87. ucontrol->value.integer.value[0] = mix->deemphasis ? 1 : 0;
  88. return 0;
  89. }
  90. static int daca_put_deemphasis(struct snd_kcontrol *kcontrol,
  91. struct snd_ctl_elem_value *ucontrol)
  92. {
  93. struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
  94. struct pmac_daca *mix;
  95. int change;
  96. if (! (mix = chip->mixer_data))
  97. return -ENODEV;
  98. change = mix->deemphasis != ucontrol->value.integer.value[0];
  99. if (change) {
  100. mix->deemphasis = !!ucontrol->value.integer.value[0];
  101. daca_set_volume(mix);
  102. }
  103. return change;
  104. }
  105. /* output volume */
  106. static int daca_info_volume(struct snd_kcontrol *kcontrol,
  107. struct snd_ctl_elem_info *uinfo)
  108. {
  109. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  110. uinfo->count = 2;
  111. uinfo->value.integer.min = 0;
  112. uinfo->value.integer.max = DACA_VOL_MAX;
  113. return 0;
  114. }
  115. static int daca_get_volume(struct snd_kcontrol *kcontrol,
  116. struct snd_ctl_elem_value *ucontrol)
  117. {
  118. struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
  119. struct pmac_daca *mix;
  120. if (! (mix = chip->mixer_data))
  121. return -ENODEV;
  122. ucontrol->value.integer.value[0] = mix->left_vol;
  123. ucontrol->value.integer.value[1] = mix->right_vol;
  124. return 0;
  125. }
  126. static int daca_put_volume(struct snd_kcontrol *kcontrol,
  127. struct snd_ctl_elem_value *ucontrol)
  128. {
  129. struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
  130. struct pmac_daca *mix;
  131. unsigned int vol[2];
  132. int change;
  133. if (! (mix = chip->mixer_data))
  134. return -ENODEV;
  135. vol[0] = ucontrol->value.integer.value[0];
  136. vol[1] = ucontrol->value.integer.value[1];
  137. if (vol[0] > DACA_VOL_MAX || vol[1] > DACA_VOL_MAX)
  138. return -EINVAL;
  139. change = mix->left_vol != vol[0] ||
  140. mix->right_vol != vol[1];
  141. if (change) {
  142. mix->left_vol = vol[0];
  143. mix->right_vol = vol[1];
  144. daca_set_volume(mix);
  145. }
  146. return change;
  147. }
  148. /* amplifier switch */
  149. #define daca_info_amp daca_info_deemphasis
  150. static int daca_get_amp(struct snd_kcontrol *kcontrol,
  151. struct snd_ctl_elem_value *ucontrol)
  152. {
  153. struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
  154. struct pmac_daca *mix;
  155. if (! (mix = chip->mixer_data))
  156. return -ENODEV;
  157. ucontrol->value.integer.value[0] = mix->amp_on ? 1 : 0;
  158. return 0;
  159. }
  160. static int daca_put_amp(struct snd_kcontrol *kcontrol,
  161. struct snd_ctl_elem_value *ucontrol)
  162. {
  163. struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
  164. struct pmac_daca *mix;
  165. int change;
  166. if (! (mix = chip->mixer_data))
  167. return -ENODEV;
  168. change = mix->amp_on != ucontrol->value.integer.value[0];
  169. if (change) {
  170. mix->amp_on = !!ucontrol->value.integer.value[0];
  171. i2c_smbus_write_byte_data(mix->i2c.client, DACA_REG_GCFG,
  172. mix->amp_on ? 0x05 : 0x04);
  173. }
  174. return change;
  175. }
  176. static struct snd_kcontrol_new daca_mixers[] = {
  177. { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  178. .name = "Deemphasis Switch",
  179. .info = daca_info_deemphasis,
  180. .get = daca_get_deemphasis,
  181. .put = daca_put_deemphasis
  182. },
  183. { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  184. .name = "Master Playback Volume",
  185. .info = daca_info_volume,
  186. .get = daca_get_volume,
  187. .put = daca_put_volume
  188. },
  189. { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  190. .name = "Power Amplifier Switch",
  191. .info = daca_info_amp,
  192. .get = daca_get_amp,
  193. .put = daca_put_amp
  194. },
  195. };
  196. #ifdef CONFIG_PM
  197. static void daca_resume(struct snd_pmac *chip)
  198. {
  199. struct pmac_daca *mix = chip->mixer_data;
  200. i2c_smbus_write_byte_data(mix->i2c.client, DACA_REG_SR, 0x08);
  201. i2c_smbus_write_byte_data(mix->i2c.client, DACA_REG_GCFG,
  202. mix->amp_on ? 0x05 : 0x04);
  203. daca_set_volume(mix);
  204. }
  205. #endif /* CONFIG_PM */
  206. static void daca_cleanup(struct snd_pmac *chip)
  207. {
  208. struct pmac_daca *mix = chip->mixer_data;
  209. if (! mix)
  210. return;
  211. snd_pmac_keywest_cleanup(&mix->i2c);
  212. kfree(mix);
  213. chip->mixer_data = NULL;
  214. }
  215. /* exported */
  216. int snd_pmac_daca_init(struct snd_pmac *chip)
  217. {
  218. int i, err;
  219. struct pmac_daca *mix;
  220. request_module("i2c-powermac");
  221. mix = kzalloc(sizeof(*mix), GFP_KERNEL);
  222. if (! mix)
  223. return -ENOMEM;
  224. chip->mixer_data = mix;
  225. chip->mixer_free = daca_cleanup;
  226. mix->amp_on = 1; /* default on */
  227. mix->i2c.addr = DACA_I2C_ADDR;
  228. mix->i2c.init_client = daca_init_client;
  229. mix->i2c.name = "DACA";
  230. if ((err = snd_pmac_keywest_init(&mix->i2c)) < 0)
  231. return err;
  232. /*
  233. * build mixers
  234. */
  235. strcpy(chip->card->mixername, "PowerMac DACA");
  236. for (i = 0; i < ARRAY_SIZE(daca_mixers); i++) {
  237. if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&daca_mixers[i], chip))) < 0)
  238. return err;
  239. }
  240. #ifdef CONFIG_PM
  241. chip->resume = daca_resume;
  242. #endif
  243. return 0;
  244. }