sa1111-uda1341.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:6k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * Glue audio driver for the SA1111 compagnon chip & Philips UDA1341 codec.
  3.  *
  4.  * Copyright (c) 2000 John Dorsey
  5.  *
  6.  * This program is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU General Public License.
  8.  *
  9.  * History:
  10.  *
  11.  * 2000-09-04 John Dorsey SA-1111 Serial Audio Controller support
  12.  *  was initially added to the sa1100-uda1341.c
  13.  *  driver.
  14.  *
  15.  * 2001-06-03 Nicolas Pitre Made this file a separate module, based on
  16.  *  the former sa1100-uda1341.c driver.
  17.  *
  18.  * 2001-09-23 Russell King Remove old L3 bus driver.
  19.  */
  20. #include <linux/config.h>
  21. #include <linux/module.h>
  22. #include <linux/init.h>
  23. #include <linux/types.h>
  24. #include <linux/fs.h>
  25. #include <linux/delay.h>
  26. #include <linux/sched.h>
  27. #include <linux/errno.h>
  28. #include <linux/sound.h>
  29. #include <linux/soundcard.h>
  30. #include <linux/ioport.h>
  31. #include <linux/pm.h>
  32. #include <linux/l3/l3.h>
  33. #include <linux/l3/uda1341.h>
  34. #include <asm/semaphore.h>
  35. #include <asm/mach-types.h>
  36. #include <asm/uaccess.h>
  37. #include <asm/hardware.h>
  38. #include <asm/dma.h>
  39. #include <asm/arch/assabet.h>
  40. #include <asm/hardware/sa1111.h>
  41. #include "sa1100-audio.h"
  42. #undef DEBUG
  43. #ifdef DEBUG
  44. #define DPRINTK( x... )  printk( ##x )
  45. #else
  46. #define DPRINTK( x... )
  47. #endif
  48. /*
  49.  * Definitions
  50.  */
  51. #define AUDIO_RATE_DEFAULT 22050
  52. #define AUDIO_CLK_BASE 561600
  53. /*
  54.  * Mixer interface
  55.  */
  56. static struct l3_client uda1341;
  57. static int
  58. mixer_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
  59. {
  60. /*
  61.  * We only accept mixer (type 'M') ioctls.
  62.  */
  63. if (_IOC_TYPE(cmd) != 'M')
  64. return -EINVAL;
  65. return l3_command(&uda1341, cmd, (void *)arg);
  66. }
  67. static struct file_operations uda1341_mixer_fops = {
  68. ioctl: mixer_ioctl,
  69. owner: THIS_MODULE
  70. };
  71. /*
  72.  * Audio interface
  73.  */
  74. static int audio_clk_div = (AUDIO_CLK_BASE + AUDIO_RATE_DEFAULT/2)/AUDIO_RATE_DEFAULT;
  75. static void sa1111_audio_init(void *dummy)
  76. {
  77. #ifdef CONFIG_ASSABET_NEPONSET
  78. if (machine_is_assabet()) {
  79. /* Select I2S audio (instead of AC-Link) */
  80. AUD_CTL = AUD_SEL_1341;
  81. }
  82. #endif
  83. #ifdef CONFIG_SA1100_JORNADA720
  84. if (machine_is_jornada720()) {
  85. /* LDD4 is speaker, LDD3 is microphone */
  86. PPSR &= ~(PPC_LDD3 | PPC_LDD4);
  87. PPDR |= PPC_LDD3 | PPC_LDD4;
  88. PPSR |= PPC_LDD4; /* enable speaker */
  89. PPSR |= PPC_LDD3; /* enable microphone */
  90. }
  91. #endif
  92. SBI_SKCR &= ~SKCR_SELAC;
  93. /* Enable the I2S clock and L3 bus clock: */
  94. SKPCR |= (SKPCR_I2SCLKEN | SKPCR_L3CLKEN);
  95. /* Activate and reset the Serial Audio Controller */
  96. SACR0 |= (SACR0_ENB | SACR0_RST);
  97. mdelay(5);
  98. SACR0 &= ~SACR0_RST;
  99. /* For I2S, BIT_CLK is supplied internally. The "SA-1111
  100.  * Specification Update" mentions that the BCKD bit should
  101.  * be interpreted as "0 = output". Default clock divider
  102.  * is 22.05kHz.
  103.  *
  104.  * Select I2S, L3 bus. "Recording" and "Replaying"
  105.  * (receive and transmit) are enabled.
  106.  */
  107. SACR1 = SACR1_L3EN;
  108. SKAUD = audio_clk_div - 1;
  109. /* Initialize the UDA1341 internal state */
  110. l3_open(&uda1341);
  111. }
  112. static void sa1111_audio_shutdown(void *dummy)
  113. {
  114. l3_close(&uda1341);
  115. SACR0 &= ~SACR0_ENB;
  116. }
  117. static int sa1111_audio_ioctl( struct inode *inode, struct file *file,
  118. uint cmd, ulong arg)
  119. {
  120. long val;
  121. int ret = 0;
  122. switch (cmd) {
  123. case SNDCTL_DSP_STEREO:
  124. ret = get_user(val, (int *) arg);
  125. if (ret)
  126. return ret;
  127. /* the UDA1341 is stereo only */
  128. ret = (val == 0) ? -EINVAL : 1;
  129. return put_user(ret, (int *) arg);
  130. case SNDCTL_DSP_CHANNELS:
  131. case SOUND_PCM_READ_CHANNELS:
  132. /* the UDA1341 is stereo only */
  133. return put_user(2, (long *) arg);
  134. case SNDCTL_DSP_SPEED:
  135. ret = get_user(val, (long *) arg);
  136. if (ret) break;
  137. if (val < 8000) val = 8000;
  138. if (val > 48000) val = 48000;
  139. audio_clk_div = (AUDIO_CLK_BASE + val/2)/val;
  140. SKAUD = audio_clk_div - 1;
  141. /* fall through */
  142. case SOUND_PCM_READ_RATE:
  143. return put_user(AUDIO_CLK_BASE/audio_clk_div, (long *) arg);
  144. case SNDCTL_DSP_SETFMT:
  145. case SNDCTL_DSP_GETFMTS:
  146. /* we can do 16-bit only */
  147. return put_user(AFMT_S16_LE, (long *) arg);
  148. default:
  149. /* Maybe this is meant for the mixer (as per OSS Docs) */
  150. return mixer_ioctl(inode, file, cmd, arg);
  151. }
  152. return ret;
  153. }
  154. static audio_stream_t output_stream, input_stream;
  155. static audio_state_t audio_state = {
  156. output_stream: &output_stream,
  157. input_stream: &input_stream,
  158. skip_dma_init: 1,  /* done locally */
  159. hw_init: sa1111_audio_init,
  160. hw_shutdown: sa1111_audio_shutdown,
  161. client_ioctl: sa1111_audio_ioctl,
  162. sem: __MUTEX_INITIALIZER(audio_state.sem),
  163. };
  164. static int sa1111_audio_open(struct inode *inode, struct file *file)
  165. {
  166.         return sa1100_audio_attach(inode, file, &audio_state);
  167. }
  168. /*
  169.  * Missing fields of this structure will be patched with the call
  170.  * to sa1100_audio_attach().
  171.  */
  172. static struct file_operations sa1111_audio_fops = {
  173. open: sa1111_audio_open,
  174. owner: THIS_MODULE
  175. };
  176. static int audio_dev_id, mixer_dev_id;
  177. static int __init sa1111_uda1341_init(void)
  178. {
  179. struct uda1341_cfg cfg;
  180. int ret;
  181. if ( !( (machine_is_assabet() && machine_has_neponset()) ||
  182. machine_is_jornada720() ||
  183. machine_is_badge4() ))
  184. return -ENODEV;
  185. if (!request_mem_region(_SACR0, 512, "sound"))
  186. return -EBUSY;
  187. ret = l3_attach_client(&uda1341, "l3-sa1111", "uda1341");
  188. if (ret)
  189. goto out;
  190. /* Acquire and initialize DMA */
  191. ret = sa1111_sac_request_dma(&output_stream.dma_ch, "SA1111 audio out",
  192.      SA1111_SAC_XMT_CHANNEL);
  193. if (ret < 0)
  194. goto release_l3;
  195. ret = sa1111_sac_request_dma(&input_stream.dma_ch, "SA1111 audio in",
  196.      SA1111_SAC_RCV_CHANNEL);
  197. if (ret < 0)
  198. goto release_dma;
  199. cfg.fs     = 256;
  200. cfg.format = FMT_I2S;
  201. l3_command(&uda1341, L3_UDA1341_CONFIGURE, &cfg);
  202. /* register devices */
  203. audio_dev_id = register_sound_dsp(&sa1111_audio_fops, -1);
  204. mixer_dev_id = register_sound_mixer(&uda1341_mixer_fops, -1);
  205. printk(KERN_INFO "Sound: SA1111 UDA1341: dsp id %d mixer id %dn",
  206. audio_dev_id, mixer_dev_id);
  207. return 0;
  208. release_dma:
  209. sa1100_free_dma(output_stream.dma_ch);
  210. release_l3:
  211. l3_detach_client(&uda1341);
  212. out:
  213. release_mem_region(_SACR0, 512);
  214. return ret;
  215. }
  216. static void __exit sa1111_uda1341_exit(void)
  217. {
  218. unregister_sound_dsp(audio_dev_id);
  219. unregister_sound_mixer(mixer_dev_id);
  220. sa1100_free_dma(output_stream.dma_ch);
  221. sa1100_free_dma(input_stream.dma_ch);
  222. l3_detach_client(&uda1341);
  223. release_mem_region(_SACR0, 512);
  224. }
  225. module_init(sa1111_uda1341_init);
  226. module_exit(sa1111_uda1341_exit);
  227. MODULE_AUTHOR("John Dorsey, Nicolas Pitre");
  228. MODULE_DESCRIPTION("Glue audio driver for the SA1111 compagnon chip & Philips UDA1341 codec.");
  229. EXPORT_NO_SYMBOLS;