Qt触摸屏音频驱动移植

Linux大全评论479 views阅读模式
  1. #include <linux/module.h>   
  2. #include <linux/init.h>   
  3. #include <linux/fs.h>   
  4. #include <linux/delay.h>   
  5. #include <linux/poll.h>   
  6. #include <linux/interrupt.h>   
  7. #include <linux/sound.h>   
  8. #include <linux/soundcard.h>   
  9. #include <linux/clk.h>   
  10. #include <linux/platform_device.h>   
  11. #include <linux/pm.h>   
  12. #include <linux/wait.h>   
  13.   
  14. #include <asm/uaccess.h>   
  15. #include <asm/io.h>   
  16. #include <asm/hardware.h>   
  17. #include <asm/semaphore.h>   
  18. #include <asm/dma.h>   
  19. #include <asm/arch/dma.h>   
  20. #include <asm/arch/regs-gpio.h>   
  21. #include <asm/plat-s3c24xx/clock.h>   
  22. #include <asm/arch/regs-clock.h>   
  23. #include <linux/dma-mapping.h>   
  24. #include <asm/arch/hardware.h>   
  25. #include <asm/arch/map.h>   
  26. #include <asm/arch/regs-iis.h>   
  27. #include <asm/plat-s3c24xx/devs.h>   
  28.   
  29. #define PFX "s3c2410-uda1341-superlp: "   
  30.   
  31. #define RESSIZE(ressource) (((ressource)->end - (ressource)->start)+1)   
  32.   
  33. #define MAX_DMA_CHANNELS 0   
  34.   
  35. #define L3MODE      S3C2410_GPB2   
  36. #define L3MODE_OUTP S3C2410_GPB2_OUTP   
  37. #define L3CLOCK     S3C2410_GPB4   
  38. #define L3CLOCK_OUTP S3C2410_GPB4_OUTP   
  39. #define L3DATA      S3C2410_GPB3   
  40. #define L3DATA_OUTP S3C2410_GPB3_OUTP   
  41. /* The S3C2410 has four internal DMA channels. */  
  42.   
  43. #define MAX_S3C2410_DMA_CHANNELS S3C2410_DMA_CHANNELS   
  44.   
  45. #define DMA_CH1 DMACH_I2S_IN   
  46. #define DMA_CH2 DMACH_I2S_OUT   
  47.   
  48. #define DMA_BUF_WR 1   
  49. #define DMA_BUF_RD 0   
  50.   
  51.   
  52. #define dma_wrreg(chan, reg, val) writel((val), (chan)->regs + (reg))   
  53.   
  54. /************************* add by lfc **************************/  
  55.   
  56. #define UData(Data) (Data)   
  57.   
  58. /*  
  59.  * MACRO: Fld  
  60.  *  
  61.  * Purpose  
  62.  *    The macro "Fld" encodes a bit field, given its size and its shift value  
  63.  *    with respect to bit 0.  
  64.  *  
  65.  * Note  
  66.  *    A more intuitive way to encode bit fields would have been to use their  
  67.  *    mask. However, extracting size and shift value information from a bit  
  68.  *    field's mask is cumbersome and might break the assembler (255-character  
  69.  *    line-size limit).  
  70.  *  
  71.  * Input  
  72.  *    Size       Size of the bit field, in number of bits.  
  73.  *    Shft       Shift value of the bit field with respect to bit 0.  
  74.  *  
  75.  * Output  
  76.  *    Fld        Encoded bit field.  
  77.  */  
  78.   
  79. #define Fld(Size, Shft) (((Size) << 16) + (Shft))   
  80.   
  81. /*  
  82.  * MACROS: FSize, FShft, FMsk, FAlnMsk, F1stBit  
  83.  *  
  84.  * Purpose  
  85.  *    The macros "FSize", "FShft", "FMsk", "FAlnMsk", and "F1stBit" return  
  86.  *    the size, shift value, mask, aligned mask, and first bit of a  
  87.  *    bit field.  
  88.  *  
  89.  * Input  
  90.  *    Field      Encoded bit field (using the macro "Fld").  
  91.  *  
  92.  * Output  
  93.  *    FSize      Size of the bit field, in number of bits.  
  94.  *    FShft      Shift value of the bit field with respect to bit 0.  
  95.  *    FMsk       Mask for the bit field.  
  96.  *    FAlnMsk    Mask for the bit field, aligned on bit 0.  
  97.  *    F1stBit    First bit of the bit field.  
  98.  */  
  99.   
  100. #define FSize(Field) ((Field) >> 16)   
  101. #define FShft(Field) ((Field) & 0x0000FFFF)   
  102.   
  103. /*  
  104.  * MACRO: FInsrt  
  105.  *  
  106.  * Purpose  
  107.  *    The macro "FInsrt" inserts a value into a bit field by shifting the  
  108.  *    former appropriately.  
  109.  *  
  110.  * Input  
  111.  *    Value      Bit-field value.  
  112.  *    Field      Encoded bit field (using the macro "Fld").  
  113.  *  
  114.  * Output  
  115.  *    FInsrt     Bit-field value positioned appropriately.  
  116.  */  
  117.   
  118. #define FInsrt(Value, Field) (UData (Value) << FShft (Field))   
  119.   
  120.   
  121. #define fIISPSR_A Fld(5, 5) /* Prescaler Control A */   
  122. #define IISPSR_A(x) FInsrt((x), fIISPSR_A)   
  123. #define fIISPSR_B Fld(5, 0) /* Prescaler Control B */   
  124. #define IISPSR_B(x) FInsrt((x), fIISPSR_B)   
  125. /**************************** end add **************************/  
  126.   
  127. static struct clk *iis_clock;   
  128. static void __iomem *iis_base;   
  129.   
  130. static struct s3c2410_dma_client s3c2410iis_dma_out= {   
  131.     .name = "I2SSDO",   
  132. };   
  133.   
  134. static struct s3c2410_dma_client s3c2410iis_dma_in = {   
  135.     .name = "I2SSDI",   
  136. };   
  137.   
  138. //#define DEBUG   
  139.   
  140. #ifdef DEBUG   
  141. #define DPRINTK printk   
  142. #else   
  143. #define DPRINTK( x... )   
  144. #endif   
  145.   
  146. static void init_s3c2410_iis_bus_rx(void);   
  147. static void init_s3c2410_iis_bus_tx(void);   
  148.   
  149. #define DEF_VOLUME 80   
  150.   
  151. /* UDA1341 Register bits */  
  152. #define UDA1341_ADDR 0x14   
  153.   
  154. #define UDA1341_REG_DATA0 (UDA1341_ADDR + 0)   
  155. #define UDA1341_REG_STATUS (UDA1341_ADDR + 2)   
  156.   
  157. /* status control */  
  158. #define STAT0 (0x00)   
  159. #define STAT0_RST (1 << 6)   
  160. #define STAT0_SC_MASK (3 << 4)   
  161. #define STAT0_SC_512FS (0 << 4)   
  162. #define STAT0_SC_384FS (1 << 4)   
  163. #define STAT0_SC_256FS (2 << 4)   
  164. #define STAT0_IF_MASK (7 << 1)   
  165. #define STAT0_IF_I2S (0 << 1)   
  166. #define STAT0_IF_LSB16 (1 << 1)   
  167. #define STAT0_IF_LSB18 (2 << 1)   
  168. #define STAT0_IF_LSB20 (3 << 1)   
  169. #define STAT0_IF_MSB (4 << 1)   
  170. #define STAT0_IF_LSB16MSB (5 << 1)   
  171. #define STAT0_IF_LSB18MSB (6 << 1)   
  172. #define STAT0_IF_LSB20MSB (7 << 1)   
  173. #define STAT0_DC_FILTER (1 << 0)   
  174. #define STAT0_DC_NO_FILTER (0 << 0)   
  175.   
  176. #define STAT1 (0x80)   
  177. #define STAT1_DAC_GAIN (1 << 6) /* gain of DAC */   
  178. #define STAT1_ADC_GAIN (1 << 5) /* gain of ADC */   
  179. #define STAT1_ADC_POL (1 << 4) /* polarity of ADC */   
  180. #define STAT1_DAC_POL (1 << 3) /* polarity of DAC */   
  181. #define STAT1_DBL_SPD (1 << 2) /* double speed playback */   
  182. #define STAT1_ADC_ON (1 << 1) /* ADC powered */   
  183. #define STAT1_DAC_ON (1 << 0) /* DAC powered */   
  184.   
  185. /* data0 direct control */  
  186. #define DATA0 (0x00)   
  187. #define DATA0_VOLUME_MASK (0x3f)   
  188. #define DATA0_VOLUME(x) (x)   
  189.   
  190. #define DATA1 (0x40)   
  191. #define DATA1_BASS(x) ((x) << 2)   
  192. #define DATA1_BASS_MASK (15 << 2)   
  193. #define DATA1_TREBLE(x) ((x))   
  194. #define DATA1_TREBLE_MASK (3)   
  195.   
  196. #define DATA2 (0x80)   
  197. #define DATA2_PEAKAFTER (0x1 << 5)   
  198. #define DATA2_DEEMP_NONE (0x0 << 3)   
  199. #define DATA2_DEEMP_32KHz (0x1 << 3)   
  200. #define DATA2_DEEMP_44KHz (0x2 << 3)   
  201. #define DATA2_DEEMP_48KHz (0x3 << 3)   
  202. #define DATA2_MUTE (0x1 << 2)   
  203. #define DATA2_FILTER_FLAT (0x0 << 0)   
  204. #define DATA2_FILTER_MIN (0x1 << 0)   
  205. #define DATA2_FILTER_MAX (0x3 << 0)   
  206. /* data0 extend control */  
  207. #define EXTADDR(n) (0xc0 | (n))   
  208. #define EXTDATA(d) (0xe0 | (d))   
  209.   
  210. #define EXT0 0   
  211. #define EXT0_CH1_GAIN(x) (x)   
  212. #define EXT1 1   
  213. #define EXT1_CH2_GAIN(x) (x)   
  214. #define EXT2 2   
  215. #define EXT2_MIC_GAIN_MASK (7 << 2)   
  216. #define EXT2_MIC_GAIN(x) ((x) << 2)   
  217. #define EXT2_MIXMODE_DOUBLEDIFF (0)   
  218. #define EXT2_MIXMODE_CH1 (1)   
  219. #define EXT2_MIXMODE_CH2 (2)   
  220. #define EXT2_MIXMODE_MIX (3)   
  221. #define EXT4 4   
  222. #define EXT4_AGC_ENABLE (1 << 4)   
  223. #define EXT4_INPUT_GAIN_MASK (3)   
  224. #define EXT4_INPUT_GAIN(x) ((x) & 3)   
  225. #define EXT5 5   
  226. #define EXT5_INPUT_GAIN(x) ((x) >> 2)   
  227. #define EXT6 6   
  228. #define EXT6_AGC_CONSTANT_MASK (7 << 2)   
  229. #define EXT6_AGC_CONSTANT(x) ((x) << 2)   
  230. #define EXT6_AGC_LEVEL_MASK (3)   
  231. #define EXT6_AGC_LEVEL(x) (x)   
  232.   
  233. #define AUDIO_NAME "UDA1341"   
  234. #define AUDIO_NAME_VERBOSE "UDA1341 audio driver"   
  235.   
  236. #define AUDIO_FMT_MASK (AFMT_S16_LE)   
  237. #define AUDIO_FMT_DEFAULT (AFMT_S16_LE)   
  238.   
  239. #define AUDIO_CHANNELS_DEFAULT 2   
  240. #define AUDIO_RATE_DEFAULT 44100   
  241.   
  242. #define AUDIO_NBFRAGS_DEFAULT 8   
  243. #define AUDIO_FRAGSIZE_DEFAULT 8192   
  244.   
  245. #define S_CLOCK_FREQ 384   
  246. #define PCM_ABS(a) (a < 0 ? -a : a)   
  247.   
  248. typedef struct {   
  249.     int size; /* buffer size */  
  250.     char *start; /* point to actual buffer */  
  251.     dma_addr_t dma_addr; /* physical buffer address */  
  252.     struct semaphore sem; /* down before touching the buffer */  
  253.     atomic_t count;   
  254.     wait_queue_head_t wait;   
  255.     int master; /* owner for buffer allocation, contain size when true */  
  256. } audio_buf_t;   
  257.   
  258. typedef struct {   
  259.     audio_buf_t *buffers; /* pointer to audio buffer structures */  
  260.     audio_buf_t *buf; /* current buffer used by read/write */  
  261.     u_int buf_idx; /* index for the pointer above */  
  262.     u_int fragsize; /* fragment i.e. buffer size */  
  263.     u_int nbfrags; /* nbr of fragments */  
  264.     dmach_t dma_ch; /* DMA channel (channel2 for audio) */  
  265.     u_int dma_ok;   
  266. } audio_stream_t;   
  267.   
  268. /*  
  269. * 驱动对于内存是这样使用的:  
  270. * 把buffers所指向的内存分成nbfragsxfragsize的空间(每一块的大小为fragsize,供分成nbfrags块)  
  271. * buf指向当前所使用的内存块,buf_idx只是内存块序号  
  272. */  
  273.   
  274. static audio_stream_t output_stream;   
  275. static audio_stream_t input_stream; /* input */  
  276.   
  277. #define NEXT_BUF(_s_,_b_) { \   
  278. (_s_)->_b_##_idx++; \   
  279. (_s_)->_b_##_idx %= (_s_)->nbfrags; \   
  280. (_s_)->_b_ = (_s_)->buffers + (_s_)->_b_##_idx; }   
  281.   
  282.   
  283. static u_int audio_rate;   
  284. static int audio_channels;   
  285. static int audio_fmt;   
  286. static u_int audio_fragsize;   
  287. static u_int audio_nbfrags;   
  288.   
  289.   
  290. static int audio_rd_refcount;   
  291. static int audio_wr_refcount;   
  292. #define audio_active (audio_rd_refcount | audio_wr_refcount)   
  293.   
  294. static int audio_dev_dsp;   
  295. static int audio_dev_mixer;   
  296. static int audio_mix_modcnt;   
  297.   
  298. static int uda1341_volume;   
  299. //static u8 uda_sampling;   
  300. static int uda1341_boost;   
  301. static int uda1341_treble;   
  302. static int mixer_igain=0x4; /* -6db*/  
  303.   
  304. static void uda1341_l3_address(u8 data)   
  305. {   
  306.  int i;   
  307.  unsigned long flags;   
  308.   
  309.  local_irq_save(flags);   
  310.   
  311.  s3c2410_gpio_setpin(L3MODE,0);   
  312.   
  313.  s3c2410_gpio_setpin(L3CLOCK,1);   
  314.   
  315.  udelay(1);   
  316.   
  317.  for (i = 0; i < 8; i++)   
  318.  {   
  319.   if (data & 0x1)   
  320.   {   
  321.    s3c2410_gpio_setpin(L3CLOCK,0);   
  322.    s3c2410_gpio_setpin(L3DATA,1);   
  323.    udelay(1);   
  324.    s3c2410_gpio_setpin(L3CLOCK,1);   
  325.   }else {   
  326.    s3c2410_gpio_setpin(L3CLOCK,0);   
  327.    s3c2410_gpio_setpin(L3DATA,0);   
  328.    udelay(1);   
  329.    s3c2410_gpio_setpin(L3CLOCK,1);   
  330.   }   
  331.   
  332.   data >>= 1;   
  333.  }   
  334.   
  335.  s3c2410_gpio_setpin(L3MODE,1);   
  336.  s3c2410_gpio_setpin(L3CLOCK,1);   
  337.     
  338.  local_irq_restore(flags);   
  339. }   
  340.   
  341. static void uda1341_l3_data(u8 data)   
  342. {   
  343.  int i;   
  344.  unsigned long flags;   
  345.   
  346.  local_irq_save(flags);   
  347.     
  348.  udelay(1);   
  349.   
  350.  for (i = 0; i < 8; i++)   
  351.  {   
  352.   if (data & 0x1)   
  353.   {   
  354.    s3c2410_gpio_setpin(L3CLOCK,0);   
  355.    s3c2410_gpio_setpin(L3DATA,1);   
  356.    udelay(1);   
  357.    s3c2410_gpio_setpin(L3CLOCK,1);   
  358.   } else {   
  359.    s3c2410_gpio_setpin(L3CLOCK,0);   
  360.    s3c2410_gpio_setpin(L3DATA,0);   
  361.    udelay(1);   
  362.    s3c2410_gpio_setpin(L3CLOCK,1);   
  363.   }   
  364.   
  365.   data >>= 1;   
  366.  }   
  367.   
  368.  local_irq_restore(flags);   
  369. }   
  370.   
  371. static void audio_clear_buf(audio_stream_t * s)   
  372. {   
  373.     DPRINTK("audio_clear_buf\n");   
  374.   
  375.     if(s->dma_ok)   
  376.         s3c2410_dma_ctrl(s->dma_ch, S3C2410_DMAOP_FLUSH);   
  377.   
  378.     if (s->buffers) {   
  379.         int frag;   
  380.   
  381.         for (frag = 0; frag < s->nbfrags; frag++) {   
  382.             if (!s->buffers[frag].master)   
  383.                 continue;   
  384.             dma_free_coherent(NULL,   
  385.             s->buffers[frag].master,   
  386.             s->buffers[frag].start,   
  387.             s->buffers[frag].dma_addr);   
  388.         }   
  389.         kfree(s->buffers);   
  390.         s->buffers = NULL;   
  391.     }   
  392.   
  393.     s->buf_idx = 0;   
  394.     s->buf = NULL;   
  395. }   
  396.   
  397. static int audio_setup_buf(audio_stream_t * s)   
  398. {   
  399.     int frag;   
  400.     int dmasize = 0;   
  401.     char *dmabuf = 0;   
  402.     dma_addr_t dmaphys = 0;   
  403.   
  404.     DPRINTK("audio_setup_buf\n");   
  405.     if (s->buffers)   
  406.         return -EBUSY;   
  407.   
  408.     s->nbfrags = audio_nbfrags;   
  409.     s->fragsize = audio_fragsize;   
  410.   
  411.     s->buffers = (audio_buf_t *)   
  412.     kmalloc(sizeof(audio_buf_t) * s->nbfrags, GFP_KERNEL);   
  413.     if (!s->buffers)   
  414.         goto err;   
  415.     memset(s->buffers, 0, sizeof(audio_buf_t) * s->nbfrags);   
  416.   
  417.     for (frag = 0; frag < s->nbfrags; frag++) {   
  418.         audio_buf_t *b = &s->buffers[frag];   
  419.   
  420.         if (!dmasize) {   
  421.             dmasize = (s->nbfrags - frag) * s->fragsize;   
  422.             do {   
  423.                 dmabuf = dma_alloc_coherent(NULL, dmasize, &dmaphys, GFP_KERNEL|GFP_DMA);   
  424.                 if (!dmabuf)   
  425.                     dmasize -= s->fragsize;   
  426.             } while (!dmabuf && dmasize);   
  427.             if (!dmabuf)   
  428.                 goto err;   
  429.             b->master = dmasize;   
  430.         }   
  431.   
  432.         b->start = dmabuf;   
  433.         b->dma_addr = dmaphys;   
  434.           
  435.         sema_init(&b->sem, 1);   
  436.         atomic_set(&b->count, 1);   
  437.      init_waitqueue_head(&b->wait);   
  438.        
  439.         DPRINTK("buf %d: start %p dma %d\n", frag, b->start, b->dma_addr);   
  440.   
  441.         dmabuf += s->fragsize;   
  442.         dmaphys += s->fragsize;   
  443.         dmasize -= s->fragsize;   
  444.     }   
  445.   
  446.     s->buf_idx = 0;   
  447.     s->buf = &s->buffers[0];   
  448.     return 0;   
  449.   
  450.  err:   
  451.     printk(AUDIO_NAME ": unable to allocate audio memory\n ");   
  452.     audio_clear_buf(s);   
  453.     return -ENOMEM;   
  454. }   
  455.   
  456. static void audio_dmaout_done_callback(struct s3c2410_dma_chan *ch, void *buf, int size, enum s3c2410_dma_buffresult result)   
  457. {   
  458.     audio_buf_t *b = (audio_buf_t *) buf;   
  459.   
  460.     DPRINTK("audio_dmaout_done_callback\n");   
  461.   
  462.     up(&b->sem);   
  463.  wake_up(&b->wait);   
  464. }   
  465.   
  466. static void audio_dmain_done_callback(struct s3c2410_dma_chan *ch, void *buf, int size, enum s3c2410_dma_buffresult result)   
  467. {   
  468.     audio_buf_t *b = (audio_buf_t *) buf;   
  469.   
  470.     DPRINTK("audio_dmain_done_callback\n");   
  471.   
  472.     b->size = size;   
  473.     up(&b->sem);   
  474.  wake_up(&b->wait);   
  475. }   
  476.   
  477. /* using when write */  
  478. static int audio_sync(struct file *file)   
  479. {   
  480.     audio_stream_t *s = &output_stream;   
  481.     audio_buf_t *b = s->buf;   
  482.   
  483.     DPRINTK("audio_sync\n");   
  484.   
  485.     if (!s->buffers)   
  486.         return 0;   
  487.   
  488.     if (b->size != 0) {   
  489.         down(&b->sem);   
  490.         s3c2410_dma_enqueue(s->dma_ch, (void *) b, b->dma_addr, b->size);   
  491.         b->size = 0;   
  492.         NEXT_BUF(s, buf);   
  493.     }   
  494.   
  495.     b = s->buffers + ((s->nbfrags + s->buf_idx - 1) % s->nbfrags);   
  496.     if (down_interruptible(&b->sem))   
  497.         return -EINTR;   
  498.     up(&b->sem);   
  499.   
  500.     return 0;   
  501. }   
  502.   
  503. static inline int copy_from_user_mono_stereo(char *to, const char *from, int count)   
  504. {   
  505.     u_int *dst = (u_int *)to;   
  506.     const char *end = from + count;   
  507.   
  508.     DPRINTK("copy_from_user_mono_stereo\n");   
  509.   
  510.     if (access_ok(VERIFY_READ, from, count))   
  511.         return -EFAULT;   
  512.   
  513.     if ((int)from & 0x2) {   
  514.         u_int v;   
  515.         __get_user(v, (const u_short *)from); from += 2;   
  516.         *dst++ = v | (v << 16);   
  517.     }   
  518.   
  519.     while (from < end-2) {   
  520.         u_int v, x, y;   
  521.         __get_user(v, (const u_int *)from); from += 4;   
  522.         x = v << 16;   
  523.         x |= x >> 16;   
  524.         y = v >> 16;   
  525.         y |= y << 16;   
  526.         *dst++ = x;   
  527.         *dst++ = y;   
  528.     }   
  529.   
  530.     if (from < end) {   
  531.         u_int v;   
  532.         __get_user(v, (const u_short *)from);   
  533.         *dst = v | (v << 16);   
  534.     }   
  535.   
  536.     return 0;   
  537. }   
  538.   
  539.   
  540. static ssize_t smdk2410_audio_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)   
  541. {   
  542.     const char *buffer0 = buffer;   
  543.     audio_stream_t *s = &output_stream;   
  544.     int chunksize, ret = 0;   
  545.   
  546.     DPRINTK("audio_write : start count=%d\n", count);   
  547.   
  548.     switch (file->f_flags & O_ACCMODE) {   
  549.         case O_WRONLY:   
  550.         case O_RDWR:   
  551.             break;   
  552.         default:   
  553.             DPRINTK("EPERM\n");   
  554.             return -EPERM;   
  555.     }   
  556.   
  557.     if (!s->buffers && audio_setup_buf(s)){   
  558.         DPRINTK("ENOMEM\n");   
  559.         return -ENOMEM;   
  560.     }   
  561.   
  562.     count &= ~0x03;   
  563.   
  564.     while (count > 0) {   
  565.         audio_buf_t *b = s->buf;   
  566.   
  567.         if (file->f_flags & O_NONBLOCK) {   
  568.             ret = -EAGAIN;   
  569.             if (down_trylock(&b->sem)){   
  570.                 DPRINTK("down_trylock error\n");   
  571.                 break;   
  572.             }   
  573.         } else {   
  574.             ret = -ERESTARTSYS;   
  575.             if (down_interruptible(&b->sem)){   
  576.                 DPRINTK("down_interruptible error\n");   
  577.                 break;   
  578.             }   
  579.         }   
  580.   
  581.         if (audio_channels == 2) {   
  582.             chunksize = s->fragsize - b->size;//当前内存块可供使用空间   
  583.   
  584.             if (chunksize > count)   
  585.                 chunksize = count;   
  586.                   
  587.             DPRINTK("write %d to %d\n", chunksize, s->buf_idx);   
  588.               
  589.             if (copy_from_user(b->start + b->size, buffer, chunksize)) {   
  590.                 DPRINTK("copy_from_user error\n");   
  591.                 up(&b->sem);   
  592.                 return -EFAULT;   
  593.             }   
  594.               
  595.             b->size += chunksize;//更新当前内存块的使用情况   
  596.         } else {   
  597.             chunksize = (s->fragsize - b->size) >> 1;   
  598.   
  599.             if (chunksize > count)   
  600.                 chunksize = count;   
  601.                   
  602.             DPRINTK("write %d to %d\n", chunksize*2, s->buf_idx);   
  603.               
  604.             if (copy_from_user_mono_stereo(b->start + b->size, buffer, chunksize)) {   
  605.                 DPRINTK("copy_from_user_mono_stereo error\n");   
  606.                 up(&b->sem);   
  607.                 return -EFAULT;   
  608.             }   
  609.               
  610.             b->size += chunksize*2;   
  611.         }   
  612.   
  613.         buffer += chunksize;   
  614.         count -= chunksize;   
  615.         if (b->size < s->fragsize) {   
  616.             up(&b->sem);   
  617.             break;   
  618.         }   
  619.         /* 填满一块内存就交给dma去处理 */  
  620.         if((ret = s3c2410_dma_enqueue(s->dma_ch, (void *) b, b->dma_addr, b->size))) {   
  621.             printk("dma enqueue failed.\n");   
  622.             return ret;   
  623.         }   
  624.         /* 把内存块加入dma队列后继续填写下一内存块 */  
  625.         b->size = 0;   
  626.         NEXT_BUF(s, buf);   
  627.     }   
  628.   
  629.     if ((buffer - buffer0))   
  630.         ret = buffer - buffer0;//返回已传输的字节数   
  631.   
  632.     DPRINTK("audio_write : end count=%d\n\n", ret);   
  633.   
  634.     return ret;   
  635. }   
  636.   
  637.   
  638. static ssize_t smdk2410_audio_read(struct file *file, char *buffer, size_t count, loff_t * ppos)   
  639. {   
  640.     const char *buffer0 = buffer;   
  641.     audio_stream_t *s = &input_stream;   
  642.     int chunksize, ret = 0;   
  643.   
  644.     DPRINTK("audio_read: count=%d\n", count);   
  645.     /*  
  646.     if (ppos != &file->f_pos)  
  647.         return -ESPIPE;  
  648.     */  
  649.     if (!s->buffers) {   
  650.         int i;   
  651.   
  652.         if (audio_setup_buf(s))   
  653.             return -ENOMEM;   
  654.   
  655.         for (i = 0; i < s->nbfrags; i++) {   
  656.             audio_buf_t *b = s->buf;   
  657.             down(&b->sem);   
  658.             s3c2410_dma_enqueue(s->dma_ch, (void *) b, b->dma_addr, s->fragsize);   
  659.             NEXT_BUF(s, buf);   
  660.         }   
  661.     }   
  662.   
  663.     while (count > 0) {   
  664.         audio_buf_t *b = s->buf;   
  665.   
  666.         /* Wait for a buffer to become full */  
  667.         if (file->f_flags & O_NONBLOCK) {   
  668.             ret = -EAGAIN;   
  669.             if (down_trylock(&b->sem))   
  670.                 break;   
  671.         } else {   
  672.             ret = -ERESTARTSYS;   
  673.             if (down_interruptible(&b->sem))   
  674.                 break;   
  675.         }   
  676.   
  677.         chunksize = b->size;   
  678.         if (chunksize > count)   
  679.             chunksize = count;   
  680.         DPRINTK("read %d from %d\n", chunksize, s->buf_idx);   
  681.         if (copy_to_user(buffer, b->start + s->fragsize - b->size, chunksize)) {   
  682.             up(&b->sem);   
  683.             return -EFAULT;   
  684.         }   
  685.   
  686.         b->size -= chunksize;   
  687.   
  688.         buffer += chunksize;   
  689.         count -= chunksize;   
  690.         if (b->size > 0) {   
  691.             up(&b->sem);   
  692.             break;   
  693.         }   
  694.   
  695.         /* Make current buffer available for DMA again */  
  696.         s3c2410_dma_enqueue(s->dma_ch, (void *) b, b->dma_addr, s->fragsize);   
  697.   
  698.         NEXT_BUF(s, buf);   
  699.     }   
  700.   
  701.     if ((buffer - buffer0))   
  702.         ret = buffer - buffer0;   
  703.   
  704.     // DPRINTK("audio_read: return=%d\n", ret);   
  705.   
  706.     return ret;   
  707. }   
  708.   
  709.   
  710. static unsigned int smdk2410_audio_poll(struct file *file,struct poll_table_struct *wait)   
  711. {   
  712.     unsigned int mask = 0;   
  713.     int i;   
  714.   
  715.     DPRINTK("audio_poll(): mode=%s\n", (file->f_mode & FMODE_WRITE) ? "w" : "");   
  716.   
  717.     if (file->f_mode & FMODE_READ) {   
  718.         if (!input_stream.buffers && audio_setup_buf(&input_stream))   
  719.             return -ENOMEM;   
  720.   poll_wait(file, &input_stream.buf->wait, wait);   
  721.   
  722.         for (i = 0; i < input_stream.nbfrags; i++) {   
  723.    if (atomic_read(&input_stream.buffers[i].count) > 0)   
  724.                 mask |= POLLIN | POLLWRNORM;   
  725.             break;   
  726.         }   
  727.     }   
  728.   
  729.   
  730.     if (file->f_mode & FMODE_WRITE) {   
  731.         if (!output_stream.buffers && audio_setup_buf(&output_stream))   
  732.             return -ENOMEM;   
  733.   poll_wait(file, &output_stream.buf->wait, wait);   
  734.   
  735.         for (i = 0; i < output_stream.nbfrags; i++) {   
  736.    if (atomic_read(&output_stream.buffers[i].count) > 0)   
  737.                 mask |= POLLOUT | POLLWRNORM;   
  738.             break;   
  739.         }   
  740.     }   
  741.   
  742.     DPRINTK("audio_poll() returned mask of %s\n",(mask & POLLOUT) ? "w" : "");   
  743.   
  744.     return mask;   
  745. }   
  746.   
  747.   
  748. static loff_t smdk2410_audio_llseek(struct file *file, loff_t offset, int origin)   
  749. {   
  750.     DPRINTK("smdk2410_audio_llseek\n");   
  751.     return -ESPIPE;   
  752. }   
  753.   
  754.   
  755. static int smdk2410_mixer_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)   
  756. {   
  757.     int ret;   
  758.     long val = 0;   
  759.   
  760.     DPRINTK("smdk2410_mixer_ioctl\n");   
  761.   
  762.     switch (cmd) {   
  763.         case SOUND_MIXER_INFO:   
  764.         {   
  765.             mixer_info info;   
  766.             strncpy(info.id, "UDA1341"sizeof(info.id));   
  767.             strncpy(info.name,"Philips UDA1341"sizeof(info.name));   
  768.             info.modify_counter = audio_mix_modcnt;   
  769.             return copy_to_user((void *)arg, &info, sizeof(info));   
  770.         }   
  771.   
  772.         case SOUND_OLD_MIXER_INFO:   
  773.         {   
  774.             _old_mixer_info info;   
  775.             strncpy(info.id, "UDA1341"sizeof(info.id));   
  776.             strncpy(info.name,"Philips UDA1341"sizeof(info.name));   
  777.             return copy_to_user((void *)arg, &info, sizeof(info));   
  778.         }   
  779.   
  780.         case SOUND_MIXER_READ_STEREODEVS:   
  781.             return put_user(0, (long *) arg);   
  782.   
  783.         case SOUND_MIXER_READ_CAPS:   
  784.             val = SOUND_CAP_EXCL_INPUT;   
  785.             return put_user(val, (long *) arg);   
  786.   
  787.         case SOUND_MIXER_WRITE_VOLUME:   
  788.             ret = get_user(val, (long *) arg);   
  789.             if (ret)   
  790.                 return ret;    
  791.   
  792.             uda1341_volume = 63 - (((val & 0xff) + 1) * 63) / 100;   
  793.             uda1341_l3_address(UDA1341_REG_DATA0);   
  794.             uda1341_l3_data(uda1341_volume);   
  795.             break;   
  796.   
  797.         case SOUND_MIXER_READ_VOLUME:   
  798.             val = ((63 - uda1341_volume) * 100) / 63;   
  799.             val |= val << 8;   
  800.             return put_user(val, (long *) arg);   
  801.   
  802.         case SOUND_MIXER_READ_IGAIN:   
  803.             val = ((31- mixer_igain) * 100) / 31;   
  804.             return put_user(val, (int *) arg);   
  805.   
  806.         case SOUND_MIXER_WRITE_IGAIN:   
  807.             ret = get_user(val, (int *) arg);   
  808.             if (ret)   
  809.                 return ret;   
  810.             mixer_igain = 31 - (val * 31 / 100);   
  811.             /* use mixer gain channel 1*/  
  812.             uda1341_l3_address(UDA1341_REG_DATA0);   
  813.             uda1341_l3_data(EXTADDR(EXT0));   
  814.             uda1341_l3_data(EXTDATA(EXT0_CH1_GAIN(mixer_igain)));   
  815.             break;   
  816.   
  817.         default:   
  818.             DPRINTK("mixer ioctl %u unknown\n", cmd);   
  819.             return -ENOSYS;   
  820.     }   
  821.   
  822.     audio_mix_modcnt++;   
  823.     return 0;   
  824. }   
  825.   
  826.   
  827. static int iispsr_value(int s_bit_clock, int sample_rate)   
  828. {   
  829.     int i, prescaler = 0;   
  830.     unsigned long tmpval;   
  831.     unsigned long tmpval384;   
  832.     unsigned long tmpval384min = 0xffff;   
  833.   
  834.     tmpval384 = clk_get_rate(iis_clock) / s_bit_clock;   
  835.   
  836.     for (i = 0; i < 32; i++) {   
  837.         tmpval = tmpval384/(i+1);   
  838.         if (PCM_ABS((sample_rate - tmpval)) < tmpval384min) {   
  839.             tmpval384min = PCM_ABS((sample_rate - tmpval));   
  840.             prescaler = i;   
  841.         }   
  842.     }   
  843.   
  844.     DPRINTK("prescaler = %d\n", prescaler);   
  845.   
  846.     return prescaler;   
  847. }   
  848.   
  849.   
  850. static long audio_set_dsp_speed(long val)   
  851. {   
  852.     unsigned int prescaler;   
  853.     prescaler=(IISPSR_A(iispsr_value(S_CLOCK_FREQ, val))   
  854.               | IISPSR_B(iispsr_value(S_CLOCK_FREQ, val)));   
  855.     writel(prescaler, iis_base + S3C2410_IISPSR);   
  856.   
  857.     printk(PFX "audio_set_dsp_speed:%ld prescaler:%i\n",val,prescaler);   
  858.     return (audio_rate = val);   
  859. }   
  860.   
  861. static int smdk2410_audio_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)   
  862. {   
  863.     long val;   
  864.   
  865.     DPRINTK("smdk2410_audio_ioctl\n");   
  866.   
  867.     switch (cmd) {   
  868.         case SNDCTL_DSP_SETFMT:   
  869.             get_user(val, (long *) arg);   
  870.             if (val & AUDIO_FMT_MASK) {   
  871.                 audio_fmt = val;   
  872.                 break;   
  873.             }   
  874.             else  
  875.                 return -EINVAL;   
  876.   
  877.         case SNDCTL_DSP_CHANNELS:   
  878.         case SNDCTL_DSP_STEREO:   
  879.             get_user(val, (long *) arg);   
  880.             if (cmd == SNDCTL_DSP_STEREO)   
  881.                 val = val ? 2 : 1;   
  882.             if (val != 1 && val != 2)   
  883.                 return -EINVAL;   
  884.             DPRINTK("audio_channels set to %d\n", val);   
  885.             audio_channels = val;   
  886.             break;   
  887.   
  888.         case SOUND_PCM_READ_CHANNELS:   
  889.             DPRINTK("audio_channels is %d\n", audio_channels);   
  890.             put_user(audio_channels, (long *) arg);   
  891.             break;   
  892.   
  893.         case SNDCTL_DSP_SPEED:   
  894.             get_user(val, (long *) arg);   
  895.             val = audio_set_dsp_speed(val);   
  896.             if (val < 0)   
  897.                 return -EINVAL;   
  898.             put_user(val, (long *) arg);   
  899.             break;   
  900.   
  901.         case SOUND_PCM_READ_RATE:   
  902.             put_user(audio_rate, (long *) arg);   
  903.             break;   
  904.   
  905.         case SNDCTL_DSP_GETFMTS:   
  906.             put_user(AUDIO_FMT_MASK, (long *) arg);   
  907.             break;   
  908.   
  909.         case SNDCTL_DSP_GETBLKSIZE:   
  910.             if(file->f_mode & FMODE_WRITE)   
  911.                 return put_user(audio_fragsize, (long *) arg);   
  912.             else  
  913.                 return put_user(audio_fragsize, (int *) arg);   
  914.   
  915.         case SNDCTL_DSP_SETFRAGMENT:   
  916.             if (file->f_mode & FMODE_WRITE) {   
  917.                 if (output_stream.buffers)   
  918.                     return -EBUSY;   
  919.                 get_user(val, (long *) arg);   
  920.                 audio_fragsize = 1 << (val & 0xFFFF);   
  921.                 if (audio_fragsize < 16)   
  922.                     audio_fragsize = 16;   
  923.                 if (audio_fragsize > 16384)   
  924.                     audio_fragsize = 16384;   
  925.                 audio_nbfrags = (val >> 16) & 0x7FFF;   
  926.                 if (audio_nbfrags < 2)   
  927.                     audio_nbfrags = 2;   
  928.                 if (audio_nbfrags * audio_fragsize > 128 * 1024)   
  929.                     audio_nbfrags = 128 * 1024 / audio_fragsize;   
  930.                 if (audio_setup_buf(&output_stream))   
  931.                     return -ENOMEM;   
  932.   
  933.             }   
  934.             if (file->f_mode & FMODE_READ) {   
  935.                 if (input_stream.buffers)   
  936.                     return -EBUSY;   
  937.                 get_user(val, (int *) arg);   
  938.                 audio_fragsize = 1 << (val & 0xFFFF);   
  939.                 if (audio_fragsize < 16)   
  940.                     audio_fragsize = 16;   
  941.                 if (audio_fragsize > 16384)   
  942.                     audio_fragsize = 16384;   
  943.                 audio_nbfrags = (val >> 16) & 0x7FFF;   
  944.                 if (audio_nbfrags < 2)   
  945.                     audio_nbfrags = 2;   
  946.                 if (audio_nbfrags * audio_fragsize > 128 * 1024)   
  947.                     audio_nbfrags = 128 * 1024 / audio_fragsize;   
  948.                 if (audio_setup_buf(&input_stream))   
  949.                     return -ENOMEM;   
  950.             }   
  951.             break;   
  952.   
  953.         case SNDCTL_DSP_SYNC:   
  954.             return audio_sync(file);   
  955.   
  956.         case SNDCTL_DSP_GETOSPACE:   
  957.         {   
  958.             audio_stream_t *s = &output_stream;   
  959.             audio_buf_info *inf = (audio_buf_info *) arg;    
  960.             int err = !access_ok(VERIFY_WRITE, inf, sizeof(*inf));   
  961.             int i;   
  962.             int frags = 0, bytes = 0;   
  963.   
  964.             if (err)   
  965.                 return err;   
  966.   
  967.             for (i = 0; i < s->nbfrags; i++) {   
  968.     if (atomic_read(&s->buffers[i].count) > 0) {   
  969.                     if (s->buffers[i].size == 0)   
  970.                         frags++;   
  971.                     bytes += s->fragsize - s->buffers[i].size;   
  972.                 }   
  973.             }   
  974.               
  975.             put_user(frags, &inf->fragments);   
  976.             put_user(s->nbfrags, &inf->fragstotal);   
  977.             put_user(s->fragsize, &inf->fragsize);   
  978.             put_user(bytes, &inf->bytes);   
  979.             break;   
  980.         }   
  981.   
  982.         case SNDCTL_DSP_GETISPACE:   
  983.         {   
  984.             audio_stream_t *s = &input_stream;   
  985.             audio_buf_info *inf = (audio_buf_info *) arg;   
  986.             int err = access_ok(VERIFY_WRITE, inf, sizeof(*inf));   
  987.             int i;   
  988.             int frags = 0, bytes = 0;   
  989.   
  990.             if (!(file->f_mode & FMODE_READ))   
  991.                 return -EINVAL;   
  992.   
  993.             if (err)   
  994.                 return err;   
  995.             for(i = 0; i < s->nbfrags; i++){   
  996.     if (atomic_read(&s->buffers[i].count) > 0)   
  997.                 {   
  998.                     if (s->buffers[i].size == s->fragsize)   
  999.                     frags++;   
  1000.                     bytes += s->buffers[i].size;   
  1001.                 }   
  1002.             }   
  1003.             put_user(frags, &inf->fragments);   
  1004.             put_user(s->nbfrags, &inf->fragstotal);   
  1005.             put_user(s->fragsize, &inf->fragsize);   
  1006.             put_user(bytes, &inf->bytes);   
  1007.             break;   
  1008.         }   
  1009.   
  1010.         case SNDCTL_DSP_RESET:   
  1011.             if (file->f_mode & FMODE_READ) {   
  1012.                 audio_clear_buf(&input_stream);   
  1013.             }   
  1014.             if (file->f_mode & FMODE_WRITE) {   
  1015.                 audio_clear_buf(&output_stream);   
  1016.             }   
  1017.             return 0;   
  1018.   
  1019.         case SNDCTL_DSP_NONBLOCK:   
  1020.             file->f_flags |= O_NONBLOCK;   
  1021.             return 0;   
  1022.   
  1023.         case SNDCTL_DSP_POST:   
  1024.         case SNDCTL_DSP_SUBDIVIDE:   
  1025.         case SNDCTL_DSP_GETCAPS:   
  1026.         case SNDCTL_DSP_GETTRIGGER:   
  1027.         case SNDCTL_DSP_SETTRIGGER:   
  1028.         case SNDCTL_DSP_GETIPTR:   
  1029.         case SNDCTL_DSP_GETOPTR:   
  1030.         case SNDCTL_DSP_MAPINBUF:   
  1031.         case SNDCTL_DSP_MAPOUTBUF:   
  1032.         case SNDCTL_DSP_SETSYNCRO:   
  1033.         case SNDCTL_DSP_SETDUPLEX:   
  1034.             return -ENOSYS;   
  1035.         default:   
  1036.             return smdk2410_mixer_ioctl(inode, file, cmd, arg);   
  1037.     }   
  1038.   
  1039.     return 0;   
  1040. }   
  1041.   
  1042.   
  1043. static int smdk2410_audio_open(struct inode *inode, struct file *file)   
  1044. {   
  1045.     int cold = !audio_active;   
  1046.   
  1047.     DPRINTK("audio_open\n");   
  1048.     if ((file->f_flags & O_ACCMODE) == O_RDONLY) {   
  1049.         if (audio_rd_refcount || audio_wr_refcount)   
  1050.             return -EBUSY;   
  1051.         audio_rd_refcount++;   
  1052.     } else if ((file->f_flags & O_ACCMODE) == O_WRONLY) {   
  1053.         if (audio_wr_refcount)   
  1054.             return -EBUSY;   
  1055.         audio_wr_refcount++;   
  1056.     } else if ((file->f_flags & O_ACCMODE) == O_RDWR) {   
  1057.         if (audio_rd_refcount || audio_wr_refcount)   
  1058.             return -EBUSY;   
  1059.         audio_rd_refcount++;   
  1060.         audio_wr_refcount++;   
  1061.     } else  
  1062.         return -EINVAL;   
  1063.   
  1064.     if (cold) {   
  1065.         audio_rate = AUDIO_RATE_DEFAULT;   
  1066.         audio_channels = AUDIO_CHANNELS_DEFAULT;   
  1067.         audio_fragsize = AUDIO_FRAGSIZE_DEFAULT;   
  1068.         audio_nbfrags = AUDIO_NBFRAGS_DEFAULT;   
  1069.         if ((file->f_mode & FMODE_WRITE)){   
  1070.             init_s3c2410_iis_bus_tx();   
  1071.             audio_clear_buf(&output_stream);   
  1072.   
  1073.             if (!output_stream .buffers && audio_setup_buf(&output_stream))   
  1074.                 return -ENOMEM;   
  1075.         }   
  1076.         if ((file->f_mode & FMODE_READ)){   
  1077.             init_s3c2410_iis_bus_rx();   
  1078.             audio_clear_buf(&input_stream);   
  1079.         }   
  1080.     }   
  1081.     return 0;   
  1082. }   
  1083.   
  1084.     
  1085.   
  1086. static int smdk2410_mixer_open(struct inode *inode, struct file *file)   
  1087. {   
  1088.     DPRINTK("smdk2410_mixer_open\n");   
  1089.     return 0;   
  1090. }   
  1091.   
  1092.   
  1093. static int smdk2410_audio_release(struct inode *inode, struct file *file)   
  1094. {   
  1095.     DPRINTK("audio_release\n");   
  1096.   
  1097.     if (file->f_mode & FMODE_READ) {   
  1098.         if (audio_rd_refcount == 1)   
  1099.         audio_clear_buf(&input_stream);   
  1100.         audio_rd_refcount = 0;   
  1101.     }   
  1102.   
  1103.     if(file->f_mode & FMODE_WRITE) {   
  1104.         if (audio_wr_refcount == 1) {   
  1105.             audio_sync(file);   
  1106.             audio_clear_buf(&output_stream);   
  1107.             audio_wr_refcount = 0;   
  1108.         }   
  1109.     }   
  1110.   
  1111.     return 0;   
  1112. }   
  1113.   
  1114.   
  1115. static int smdk2410_mixer_release(struct inode *inode, struct file *file)   
  1116. {   
  1117.     DPRINTK("smdk2410_mixer_release\n");   
  1118.     return 0;   
  1119. }   
  1120.   
  1121.   
  1122. static struct file_operations smdk2410_audio_fops = {   
  1123.     llseek: smdk2410_audio_llseek,   
  1124.     write: smdk2410_audio_write,   
  1125.     read: smdk2410_audio_read,   
  1126.     poll: smdk2410_audio_poll,   
  1127.     ioctl: smdk2410_audio_ioctl,   
  1128.     open: smdk2410_audio_open,   
  1129.     release: smdk2410_audio_release   
  1130. };   
  1131.   
  1132. static struct file_operations smdk2410_mixer_fops = {   
  1133.     ioctl: smdk2410_mixer_ioctl,   
  1134.     open: smdk2410_mixer_open,   
  1135.     release: smdk2410_mixer_release   
  1136. };   
  1137.   
  1138. static void init_uda1341(void)   
  1139. {   
  1140.   
  1141.     /* GPB 4: L3CLOCK */  
  1142.     /* GPB 3: L3DATA */  
  1143.     /* GPB 2: L3MODE */  
  1144.   
  1145.     unsigned long flags;   
  1146.   
  1147.     DPRINTK("init_uda1341\n");   
  1148.   
  1149.     uda1341_volume = 62 - ((DEF_VOLUME * 61) / 100);   
  1150.     uda1341_boost = 0;   
  1151.     // uda_sampling = DATA2_DEEMP_NONE;   
  1152.     // uda_sampling &= ~(DATA2_MUTE);   
  1153.   
  1154.   
  1155.     local_irq_save(flags);   
  1156.   
  1157.     s3c2410_gpio_setpin(L3MODE,1);//L3MODE=1   
  1158.     s3c2410_gpio_setpin(L3CLOCK,1);//L3CLOCK=1   
  1159.     local_irq_restore(flags);   
  1160.   
  1161.     uda1341_l3_address(UDA1341_REG_STATUS);   
  1162.     uda1341_l3_data(0x40 | STAT0_SC_384FS | STAT0_IF_MSB|STAT0_DC_FILTER); // reset uda1341   
  1163.     uda1341_l3_data(STAT1 | STAT1_ADC_ON | STAT1_DAC_ON);   
  1164.   
  1165.     uda1341_l3_address(UDA1341_REG_DATA0);   
  1166.     // uda1341_l3_data(DATA0 |DATA0_VOLUME(0x0)); // maximum volume   
  1167.     uda1341_l3_data(DATA0 | DATA0_VOLUME(uda1341_volume));//lfc   
  1168.     uda1341_l3_data(DATA1 |DATA1_BASS(uda1341_boost)| DATA1_TREBLE(0));   
  1169.     uda1341_l3_data((DATA2 |DATA2_DEEMP_NONE) &~(DATA2_MUTE));   
  1170.     uda1341_l3_data(EXTADDR(EXT2));   
  1171.     uda1341_l3_data(EXTDATA(EXT2_MIC_GAIN(0x6)) | EXT2_MIXMODE_CH1);//input channel 1 select(input channel 2 off)   
  1172. }   
  1173.   
  1174. static void init_s3c2410_iis_bus(void){   
  1175.     DPRINTK("init_s3c2410_iis_bus\n");   
  1176.     writel(0, iis_base + S3C2410_IISPSR);   
  1177.     writel(0, iis_base + S3C2410_IISCON);   
  1178.     writel(0, iis_base + S3C2410_IISMOD);   
  1179.     writel(0, iis_base + S3C2410_IISFCON);   
  1180.     clk_disable(iis_clock);   
  1181. }   
  1182.   
  1183. static void init_s3c2410_iis_bus_rx(void)   
  1184. {   
  1185.     unsigned int iiscon, iismod, iisfcon;   
  1186.     char *dstr;   
  1187.   
  1188.     DPRINTK("init_s3c2410_iis_bus_rx\n");   
  1189.     //Kill everything...   
  1190.     writel(0, iis_base + S3C2410_IISPSR);   
  1191.     writel(0, iis_base + S3C2410_IISCON);   
  1192.     writel(0, iis_base + S3C2410_IISMOD);   
  1193.     writel(0, iis_base + S3C2410_IISFCON);   
  1194.   
  1195.     clk_enable(iis_clock);   
  1196.   
  1197.     iiscon = iismod = iisfcon = 0;   
  1198.   
  1199.     //Setup basic stuff   
  1200.     iiscon |= S3C2410_IISCON_PSCEN; // Enable prescaler   
  1201.   
  1202.    // iismod |= S3C2410_IISMOD_MASTER; // Set interface to Master Mode   
  1203.     iismod |= S3C2410_IISMOD_LR_LLOW; // Low for left channel   
  1204.     iismod |= S3C2410_IISMOD_MSB; // IIS format   
  1205.     iismod |= S3C2410_IISMOD_16BIT; // Serial data bit/channel is 16 bit   
  1206.     iismod |= S3C2410_IISMOD_384FS; // Master clock freq = 384 fs   
  1207.     iismod |= S3C2410_IISMOD_32FS; // 32 fs   
  1208.   
  1209.     iisfcon|= S3C2410_IISFCON_RXDMA | S3C2410_IISFCON_RXENABLE; //Set RX FIFO acces mode to DMA   
  1210.     //iisfcon|= S3C2410_IISFCON_TXDMA; //Set RX FIFO acces mode to DMA   
  1211.   
  1212.     iiscon |= S3C2410_IISCON_RXDMAEN | S3C2410_IISCON_IISEN; //Enable RX DMA service request   
  1213.     //iiscon |= S3C2410_IISCON_TXIDLE; //Set TX channel idle   
  1214.     iiscon &= (~S3C2410_IISCON_RXIDLE);   
  1215.   
  1216.     iismod |= S3C2410_IISMOD_RXMODE; //Set RX Mode   
  1217.     iismod |= S3C2410_IISMOD_TXMODE;   
  1218.     dstr="RX";   
  1219.     //setup the prescaler   
  1220.     audio_set_dsp_speed(audio_rate);   
  1221.   
  1222.     //iiscon has to be set last - it enables the interface   
  1223.     writel(iismod, iis_base + S3C2410_IISMOD);   
  1224.     writel(iisfcon, iis_base + S3C2410_IISFCON);   
  1225.     writel(iiscon, iis_base + S3C2410_IISCON);   
  1226. }   
  1227.   
  1228. static void init_s3c2410_iis_bus_tx(void)   
  1229. {   
  1230.     unsigned int iiscon, iismod, iisfcon;   
  1231.     char *dstr;   
  1232.   
  1233.     DPRINTK("init_s3c2410_iis_bus_tx\n");   
  1234.     //Kill everything...   
  1235.     writel(0, iis_base + S3C2410_IISPSR);   
  1236.     writel(0, iis_base + S3C2410_IISCON);   
  1237.     writel(0, iis_base + S3C2410_IISMOD);   
  1238.     writel(0, iis_base + S3C2410_IISFCON);   
  1239.   
  1240.     clk_enable(iis_clock);   
  1241.   
  1242.     iiscon = iismod = iisfcon = 0;   
  1243.   
  1244.     //Setup basic stuff   
  1245.     iiscon |= S3C2410_IISCON_PSCEN; // Enable prescaler   
  1246.   
  1247.     //iismod |= S3C2410_IISMOD_MASTER; // Set interface to Master Mode   
  1248.     iismod |= S3C2410_IISMOD_LR_LLOW; // Low for left channel   
  1249.     iismod |= S3C2410_IISMOD_MSB; // MSB format   
  1250.     iismod |= S3C2410_IISMOD_16BIT; // Serial data bit/channel is 16 bit   
  1251.     iismod |= S3C2410_IISMOD_384FS; // Master clock freq = 384 fs   
  1252.     iismod |= S3C2410_IISMOD_32FS; // 32 fs   
  1253.   
  1254.     iisfcon|= S3C2410_IISFCON_RXDMA; //Set RX FIFO acces mode to DMA   
  1255.     iisfcon|= S3C2410_IISFCON_TXDMA; //Set TX FIFO acces mode to DMA   
  1256.   
  1257.     iiscon |= S3C2410_IISCON_TXDMAEN | S3C2410_IISCON_IISEN; //Enable TX DMA service request   
  1258.     //iiscon |= S3C2410_IISCON_RXIDLE; //Set RX channel idle   
  1259.     iiscon &= ~S3C2410_IISCON_TXIDLE;   
  1260.     iismod |= S3C2410_IISMOD_TXMODE; //Set TX Mode   
  1261.     iismod |= S3C2410_IISMOD_RXMODE;   
  1262.     iisfcon|= S3C2410_IISFCON_TXENABLE; //Enable TX Fifo   
  1263.     dstr="TX";   
  1264.   
  1265.     //setup the prescaler   
  1266.     audio_set_dsp_speed(audio_rate);   
  1267.   
  1268.     //iiscon has to be set last - it enables the interface   
  1269.     writel(iismod, iis_base + S3C2410_IISMOD);   
  1270.     writel(iisfcon, iis_base + S3C2410_IISFCON);   
  1271.     writel(iiscon, iis_base + S3C2410_IISCON);   
  1272. }   
  1273.   
  1274.   
  1275. static int __init audio_init_dma(audio_stream_t * s, char *desc)   
  1276. {   
  1277.     int ret ;   
  1278.     enum s3c2410_dmasrc source;   
  1279.     int hwcfg;   
  1280.     unsigned long devaddr;   
  1281.     int dcon;   
  1282.     unsigned int flags = 0;   
  1283.       
  1284.     dmach_t channel = 2;   
  1285.       
  1286.     DPRINTK("audio_init_dma\n");   
  1287.   
  1288.     if(s->dma_ch == DMA_CH2){   
  1289.         source = S3C2410_DMASRC_MEM;   
  1290.         hwcfg = 3;   
  1291.         devaddr = 0x55000010;   
  1292.         dcon = (1<<31) | (0<<30) | (0<<24);   
  1293.         flags = S3C2410_DMAF_AUTOSTART;   
  1294.   
  1295.         ret = s3c2410_dma_request(s->dma_ch, &s3c2410iis_dma_out, NULL);   
  1296.         if (ret) {   
  1297.             printk(KERN_ERR "failed to get dma channel\n");   
  1298.             return ret;   
  1299.         }    
  1300.         s3c2410_dma_devconfig(s->dma_ch, source, hwcfg, devaddr);   
  1301.         s3c2410_dma_config(s->dma_ch, 2, dcon);   
  1302.         s3c2410_dma_set_buffdone_fn(s->dma_ch, audio_dmaout_done_callback);   
  1303.         s3c2410_dma_setflags(s->dma_ch, flags);    
  1304.   
  1305.         s->dma_ok = 1;   
  1306.         return ret;   
  1307.     }   
  1308.     else if(s->dma_ch == DMA_CH1){   
  1309.         source =S3C2410_DMASRC_HW;   
  1310.         hwcfg =3;   
  1311.         devaddr = 0x55000010;   
  1312.         dcon = (1<<31) | (1<<23) | (2<<24);   
  1313.         flags = S3C2410_DMAF_AUTOSTART;   
  1314.   
  1315.         ret = s3c2410_dma_request(s->dma_ch, &s3c2410iis_dma_in, NULL);   
  1316.         if (ret) {   
  1317.             printk(KERN_ERR "failed to get dma channel\n");   
  1318.             return ret;   
  1319.         }    
  1320.            
  1321.         s3c2410_dma_devconfig(s->dma_ch, source, hwcfg, devaddr);   
  1322.         s3c2410_dma_config(s->dma_ch, 2, dcon);   
  1323.         s3c2410_dma_set_buffdone_fn(s->dma_ch, audio_dmain_done_callback);   
  1324.         s3c2410_dma_setflags(s->dma_ch, flags);   
  1325.         s->dma_ok =1;   
  1326.         return ret ;   
  1327.     }   
  1328.     else  
  1329.         return 1;   
  1330. }   
  1331.   
  1332. static int audio_clear_dma(audio_stream_t * s,struct s3c2410_dma_client *client)   
  1333. {   
  1334.     DPRINTK("audio_clear_dma\n");   
  1335.     s3c2410_dma_set_buffdone_fn(s->dma_ch, NULL);   
  1336.     s3c2410_dma_free(s->dma_ch, client);   
  1337.     return 0;   
  1338. }   
  1339.   
  1340. static int s3c2410iis_probe(struct platform_device *pdev)   
  1341. {   
  1342.     struct resource *res;   
  1343.     unsigned long flags;   
  1344.     int ret;   
  1345.   
  1346.     DPRINTK("s3c2410iis_probe\n");   
  1347.   
  1348.     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);   
  1349.     if (res == NULL) {   
  1350.         printk(KERN_INFO PFX "failed to get memory region resouce\n");   
  1351.         return -ENOENT;   
  1352.     }   
  1353.   
  1354.     //iis_base = (void *)S3C24XX_VA_IIS ;   
  1355.   
  1356.     res = request_mem_region(res->start, RESSIZE(res), pdev->name);   
  1357.         if(res == 0){   
  1358.         printk(KERN_INFO PFX "failed to request io memory region.\n");   
  1359.         return -ENOENT;   
  1360.     }   
  1361.   
  1362.     iis_base = ioremap(res->start, RESSIZE(res));   
  1363.     if(iis_base == 0){   
  1364.         printk(KERN_INFO PFX "failed to ioremap() io memory region.\n"); ret = -EINVAL;   
  1365.         goto free_mem_region;   
  1366.     }   
  1367.   
  1368.     iis_clock = clk_get(&pdev->dev, "iis");   
  1369.     if (iis_clock == NULL) {   
  1370.         printk(KERN_INFO PFX "failed to find clock source\n");   
  1371.         return -ENOENT;   
  1372.     }   
  1373.     /**************************modify by lfc*****************************/  
  1374.     clk_enable(iis_clock);   
  1375.     /*****************************end add********************************/  
  1376.     local_irq_save(flags);   
  1377.   
  1378.     /* GPB 4: L3CLOCK, OUTPUT */  
  1379.     s3c2410_gpio_cfgpin(L3CLOCK, L3CLOCK_OUTP);   
  1380.     s3c2410_gpio_pullup(L3CLOCK,1);   
  1381.     /* GPB 3: L3DATA, OUTPUT */  
  1382.     s3c2410_gpio_cfgpin(L3DATA,L3DATA_OUTP);   
  1383.     /* GPB 2: L3MODE, OUTPUT */  
  1384.     s3c2410_gpio_cfgpin(L3MODE,L3MODE_OUTP);   
  1385.     s3c2410_gpio_pullup(L3MODE,1);   
  1386.     /* GPE 3: I2SSDI */  
  1387.     s3c2410_gpio_cfgpin(S3C2410_GPE3,S3C2410_GPE3_I2SSDI);   
  1388.     s3c2410_gpio_pullup(S3C2410_GPE3,1);   
  1389.     /* GPE 0: I2SLRCK */  
  1390.     s3c2410_gpio_cfgpin(S3C2410_GPE0,S3C2410_GPE0_I2SLRCK);   
  1391.     s3c2410_gpio_pullup(S3C2410_GPE0,1);   
  1392.     /* GPE 1: I2SSCLK */  
  1393.     s3c2410_gpio_cfgpin(S3C2410_GPE1,S3C2410_GPE1_I2SSCLK);   
  1394.     s3c2410_gpio_pullup(S3C2410_GPE1,1);   
  1395.     /* GPE 2: CDCLK */  
  1396.     s3c2410_gpio_cfgpin(S3C2410_GPE2,S3C2410_GPE2_CDCLK);   
  1397.     s3c2410_gpio_pullup(S3C2410_GPE2,1);   
  1398.     /* GPE 4: I2SSDO */  
  1399.     s3c2410_gpio_cfgpin(S3C2410_GPE4,S3C2410_GPE4_I2SSDO);   
  1400.     s3c2410_gpio_pullup(S3C2410_GPE4,1);   
  1401.   
  1402.     local_irq_restore(flags);   
  1403.   
  1404.     init_s3c2410_iis_bus();   
  1405.   
  1406.     init_uda1341();   
  1407.   
  1408.     output_stream.dma_ch = DMA_CH2;   
  1409.   
  1410.     if (audio_init_dma(&output_stream, "UDA1341 out")) {   
  1411.         audio_clear_dma(&output_stream,&s3c2410iis_dma_out);   
  1412.         printk( KERN_WARNING AUDIO_NAME_VERBOSE   
  1413.         ": unable to get DMA channels\n" );   
  1414.         return -EBUSY;   
  1415.     }   
  1416.   
  1417.     input_stream.dma_ch = DMA_CH1;   
  1418.   
  1419.     if (audio_init_dma(&input_stream, "UDA1341 in")) {   
  1420.         audio_clear_dma(&input_stream,&s3c2410iis_dma_in);   
  1421.         printk( KERN_WARNING AUDIO_NAME_VERBOSE   
  1422.         ": unable to get DMA channels\n" );   
  1423.         return -EBUSY;   
  1424.     }   
  1425.   
  1426.     audio_dev_dsp = register_sound_dsp(&smdk2410_audio_fops, -1);   
  1427.     audio_dev_mixer = register_sound_mixer(&smdk2410_mixer_fops, -1);   
  1428.   
  1429.     printk(AUDIO_NAME_VERBOSE " initialized\n");   
  1430.   
  1431. free_mem_region:   
  1432.     release_mem_region(res->start, RESSIZE(res));   
  1433.   
  1434.     return 0;   
  1435. }   
  1436.   
  1437.   
  1438. static int s3c2410iis_remove(struct platform_device *dev)   
  1439. {   
  1440.     DPRINTK("s3c2410iis_remove\n");   
  1441.   
  1442.     if (iis_clock != NULL){   
  1443.         clk_disable(iis_clock);   
  1444.         clk_put(iis_clock);   
  1445.         iis_clock = NULL;   
  1446.     }   
  1447.   
  1448.     unregister_sound_dsp(audio_dev_dsp);   
  1449.     unregister_sound_mixer(audio_dev_mixer);   
  1450.     audio_clear_dma(&output_stream,&s3c2410iis_dma_out);   
  1451.     audio_clear_dma(&input_stream,&s3c2410iis_dma_in); /* input */  
  1452.     printk(AUDIO_NAME_VERBOSE " unloaded\n");   
  1453.   
  1454.     return 0;   
  1455. }   
  1456.   
  1457.   
  1458. static struct platform_driver s3c2410iis_driver = {   
  1459.     .probe = s3c2410iis_probe,   
  1460.     .remove = s3c2410iis_remove,   
  1461.     .driver = {   
  1462.         .name = "s3c2410-iis",   
  1463.         .owner = THIS_MODULE,   
  1464.     },   
  1465. };   
  1466.   
  1467. static int __init s3c2410_uda1341_init(void)   
  1468. {   
  1469.     memzero(&input_stream, sizeof(audio_stream_t));   
  1470.     memzero(&output_stream, sizeof(audio_stream_t));   
  1471.     return platform_driver_register(&s3c2410iis_driver);   
  1472. }   
  1473.   
  1474. static void __exit s3c2410_uda1341_exit(void)   
  1475. {   
  1476.     platform_driver_unregister(&s3c2410iis_driver);   
  1477. }   
  1478.   
  1479.   
  1480. module_init(s3c2410_uda1341_init);   
  1481. module_exit(s3c2410_uda1341_exit);   
  1482.   
  1483. MODULE_LICENSE("GPL");   
  1484. MODULE_DESCRIPTION("S3C2410 uda1341 sound driver");   

企鹅博客
  • 本文由 发表于 2020年6月14日 09:13:02
  • 转载请务必保留本文链接:https://www.qieseo.com/150887.html

发表评论