acw.c 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386
  1. /*
  2. * This file is part of FH8620 BSP for RT-Thread distribution.
  3. *
  4. * Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
  5. * All rights reserved
  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 along
  18. * with this program; if not, write to the Free Software Foundation, Inc.,
  19. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  20. *
  21. * Visit http://www.fullhan.com to get contact with Fullhan.
  22. *
  23. * Change Logs:
  24. * Date Author Notes
  25. */
  26. #include "acw.h"
  27. #include "fh_def.h"
  28. #include "fh_dma.h"
  29. #include "dma.h"
  30. #ifdef RT_USING_FH_ACW
  31. #if 1
  32. typedef struct
  33. {
  34. unsigned int base;
  35. void *vbase;
  36. unsigned int size;
  37. unsigned int align;
  38. }MEM_DESC;
  39. #define ACW_SELFTEST 0
  40. int buffer_malloc_withname(MEM_DESC *mem, int size, int align, char* name);
  41. #endif
  42. #define NR_DESCS_PER_CHANNEL 64
  43. #define FIX_SAMPLE_BIT 32
  44. #define ACW_HW_NUM_RX 0
  45. #define ACW_HW_NUM_TX 1
  46. #define ACW_DMA_CAP_CHANNEL 3
  47. #define ACW_DMA_PAY_CHANNEL 2
  48. #define ACW_CTRL 0x0
  49. #define ACW_TXFIFO_CTRL 0x4
  50. #define ACW_RXFIFO_CTRL 0x8
  51. #define ACW_STATUS 0x0c
  52. #define ACW_DIG_IF_CTRL 0x10
  53. #define ACW_ADC_PATH_CTRL 0x14
  54. #define ACW_ADC_ALC_CTRL 0x18
  55. #define ACW_DAC_PATH_CTRL 0x1c
  56. #define ACW_MISC_CTRL 0x20
  57. #define ACW_TXFIFO 0xf0a00100
  58. #define ACW_RXFIFO 0xf0a00200
  59. typedef char bool;
  60. #define AUDIO_DMA_PREALLOC_SIZE 128*1024
  61. #define ACW_INTR_RX_UNDERFLOW 0x10000
  62. #define ACW_INTR_RX_OVERFLOW 0x20000
  63. #define ACW_INTR_TX_UNDERFLOW 0x40000
  64. #define ACW_INTR_TX_OVERFLOW 0x80000
  65. #define PAGE_SIZE 0x1000
  66. enum audio_type
  67. {
  68. capture = 0,
  69. playback,
  70. };
  71. enum audio_state
  72. {
  73. normal = 0,
  74. xrun,
  75. stopping,
  76. running,
  77. };
  78. struct infor_record_t
  79. {
  80. int record_pid;
  81. int play_pid;
  82. }; // infor_record;
  83. struct audio_config_t {
  84. int rate;
  85. int volume;
  86. enum io_select io_type;
  87. int frame_bit;
  88. int channels;
  89. int buffer_size;
  90. int period_size;
  91. int buffer_bytes;
  92. int period_bytes;
  93. int start_threshold;
  94. int stop_threshold;
  95. };
  96. struct audio_ptr_t
  97. {
  98. struct audio_config_t cfg;
  99. enum audio_state state;
  100. long size;
  101. int hw_ptr;
  102. int appl_ptr;
  103. struct rt_mutex lock;
  104. struct device_acw dev;
  105. void *area; /*virtual pointer*/
  106. dma_addr_t addr; /*physical address*/
  107. unsigned char * mmap_addr;
  108. };
  109. struct fh_audio_cfg
  110. {
  111. struct rt_dma_device *capture_dma;
  112. struct rt_dma_device *playback_dma;
  113. struct dma_transfer *capture_trans;
  114. struct dma_transfer *plauback_trans;
  115. struct audio_ptr_t capture;
  116. struct audio_ptr_t playback;
  117. wait_queue_head_t readqueue;
  118. wait_queue_head_t writequeue;
  119. struct rt_semaphore sem_capture;
  120. struct rt_semaphore sem_playback;
  121. };
  122. typedef int s32;
  123. typedef s32 dma_cookie_t;
  124. struct fh_dma_chan
  125. {
  126. struct dma_chan *chan;
  127. void *ch_regs;
  128. unsigned char mask;
  129. unsigned char priority;
  130. bool paused;
  131. bool initialized;
  132. struct rt_mutex lock;
  133. /* these other elements are all protected by lock */
  134. unsigned long flags;
  135. dma_cookie_t completed;
  136. struct list_head active_list;
  137. struct list_head queue;
  138. struct list_head free_list;
  139. struct fh_cyclic_desc *cdesc;
  140. unsigned int descs_allocated;
  141. };
  142. struct fh_acw_dma_transfer
  143. {
  144. struct dma_chan *chan;
  145. struct dma_transfer cfg;
  146. struct scatterlist sgl;
  147. struct dma_async_tx_descriptor *desc;
  148. };
  149. struct channel_assign
  150. {
  151. int capture_channel;
  152. int playback_channel;
  153. };
  154. struct audio_dev_mod
  155. {
  156. int reg_base;
  157. struct channel_assign channel_assign;
  158. struct fh_audio_cfg *audio_config;
  159. }audio_dev;
  160. static struct work_struct playback_wq;
  161. #define WORK_QUEUE_STACK_SIZE 512
  162. #if ACW_SELFTEST
  163. #define WORK_QUEUE_PRIORITY (12)
  164. #else
  165. #define WORK_QUEUE_PRIORITY (128+12)
  166. #endif
  167. static struct rt_workqueue* playback_queue;
  168. void audio_prealloc_dma_buffer(int aiaotype,struct fh_audio_cfg *audio_config);
  169. #if ACW_SELFTEST
  170. #define BUFF_SIZE 1024*8
  171. #define TEST_PER_NO 1024
  172. #endif
  173. static void audio_callback(){
  174. rt_kprintf("# \n");
  175. }
  176. static void audio_callback_capture(){
  177. rt_kprintf("$ \n");
  178. }
  179. static struct audio_param_store_t
  180. {
  181. int input_volume;
  182. enum io_select input_io_type;
  183. } audio_param_store;
  184. void reset_dma_buff(enum audio_type type, struct fh_audio_cfg *audio_config);
  185. static void fh_acw_tx_dma_done(void *arg);
  186. static void fh_acw_rx_dma_done(struct fh_audio_cfg *arg);
  187. static bool fh_acw_dma_chan_filter(struct dma_chan *chan, void *filter_param);
  188. #define writel(v,a) SET_REG(a,v)
  189. void fh_acw_stop_playback(struct fh_audio_cfg *audio_config)
  190. {
  191. if(audio_config->playback.state == stopping)
  192. {
  193. return;
  194. }
  195. unsigned int rx_status;
  196. rx_status = readl( audio_dev.reg_base + ACW_TXFIFO_CTRL);//clear rx fifo
  197. rx_status = rx_status|(1<<4);
  198. writel(rx_status,audio_dev.reg_base + ACW_TXFIFO_CTRL);
  199. audio_config->playback.state = stopping;
  200. writel(0, audio_dev.reg_base + ACW_TXFIFO_CTRL);//tx fifo disable
  201. if(audio_config->plauback_trans->channel_number != ACW_PLY_DMA_CHAN)
  202. goto free_mem;
  203. if(!audio_config->plauback_trans->first_lli)
  204. goto free_channel;
  205. audio_config->playback_dma->ops->control(audio_config->playback_dma,RT_DEVICE_CTRL_DMA_CYCLIC_STOP,audio_config->plauback_trans);
  206. audio_config->playback_dma->ops->control(audio_config->playback_dma,RT_DEVICE_CTRL_DMA_CYCLIC_FREE,audio_config->plauback_trans);
  207. free_channel:
  208. audio_config->playback_dma->ops->control(audio_config->playback_dma,RT_DEVICE_CTRL_DMA_RELEASE_CHANNEL,audio_config->plauback_trans);
  209. if(&audio_config->sem_playback)
  210. rt_sem_release(&audio_config->sem_playback);
  211. if(&audio_config->playback.lock)
  212. rt_mutex_release(&audio_config->playback.lock);
  213. if(&playback_wq)
  214. rt_workqueue_cancel_work(playback_queue,&playback_wq);
  215. if(playback_queue)
  216. rt_workqueue_destroy(playback_queue);
  217. free_mem:
  218. if(audio_config->playback.area)
  219. fh_dma_mem_free(audio_config->playback.area);
  220. }
  221. void fh_acw_stop_capture(struct fh_audio_cfg *audio_config)
  222. {
  223. unsigned int rx_status;
  224. if(audio_config->capture.state == stopping)
  225. {
  226. rt_kprintf(" capture is stopped \n");
  227. return;
  228. }
  229. rx_status = readl( audio_dev.reg_base + ACW_RXFIFO_CTRL);//clear rx fifo
  230. rx_status = rx_status|(1<<4);
  231. writel(rx_status,audio_dev.reg_base + ACW_RXFIFO_CTRL);
  232. audio_config->capture.state = stopping;
  233. writel(0, audio_dev.reg_base + 8);//rx fifo disable
  234. if(audio_config->capture_trans->channel_number != ACW_CAP_DMA_CHAN)
  235. goto free_mem;
  236. if(!audio_config->capture_trans->first_lli)
  237. goto free_channel;
  238. audio_config->capture_dma->ops->control(audio_config->capture_dma,RT_DEVICE_CTRL_DMA_CYCLIC_STOP,audio_config->capture_trans);
  239. audio_config->capture_dma->ops->control(audio_config->capture_dma,RT_DEVICE_CTRL_DMA_CYCLIC_FREE,audio_config->capture_trans);
  240. free_channel:
  241. audio_config->capture_dma->ops->control(audio_config->capture_dma,RT_DEVICE_CTRL_DMA_RELEASE_CHANNEL,audio_config->capture_trans);
  242. if(&audio_config->sem_capture)
  243. rt_sem_release(&audio_config->sem_capture);
  244. if(&audio_config->capture.lock)
  245. rt_mutex_release(&audio_config->capture.lock);
  246. free_mem:
  247. if(audio_config->capture.area)
  248. fh_dma_mem_free( audio_config->capture.area);
  249. }
  250. void switch_io_type(enum audio_type type, enum io_select io_type)
  251. {
  252. int reg;
  253. if (capture == type)
  254. {
  255. reg = readl(audio_dev.reg_base + ACW_ADC_PATH_CTRL);
  256. if (mic_in == io_type)
  257. {
  258. rt_kprintf("audio input changed to mic_in\n");
  259. writel( reg & (~(1<<1)),audio_dev.reg_base + ACW_ADC_PATH_CTRL);
  260. reg = readl(audio_dev.reg_base + ACW_ADC_PATH_CTRL);
  261. reg = reg & (~(1<<3));
  262. reg |=(0x1<<3);
  263. writel(reg, audio_dev.reg_base + ACW_ADC_PATH_CTRL);
  264. }
  265. else if (line_in == io_type)
  266. {
  267. rt_kprintf("audio input changed to line_in\n");
  268. writel(reg | (1<<1), audio_dev.reg_base + ACW_ADC_PATH_CTRL);
  269. }
  270. }
  271. else
  272. {
  273. reg = readl(audio_dev.reg_base + ACW_DAC_PATH_CTRL);
  274. if (speaker_out == io_type)
  275. {
  276. rt_kprintf("audio output changed to speaker_out\n");
  277. reg = reg & (~(3<<21));
  278. reg = reg & (~(3<<30));
  279. writel(reg, audio_dev.reg_base + ACW_DAC_PATH_CTRL);
  280. reg = reg | (1<<21);
  281. writel(reg,audio_dev.reg_base + ACW_DAC_PATH_CTRL);
  282. reg = reg | (1<<18);
  283. writel(reg, audio_dev.reg_base + ACW_DAC_PATH_CTRL);/*unmute speaker*/
  284. reg = reg | (3<<30);
  285. writel(reg,audio_dev.reg_base + ACW_DAC_PATH_CTRL);/*mute line out*/
  286. }
  287. else if (line_out == io_type)
  288. {
  289. rt_kprintf("audio output changed to line_out\n");
  290. reg = reg & (~(3<<21));
  291. writel(reg, audio_dev.reg_base + ACW_DAC_PATH_CTRL);/*mute speaker*/
  292. reg = reg & (~(3<<30));
  293. writel(reg, audio_dev.reg_base + ACW_DAC_PATH_CTRL);/*unmute line out*/
  294. }
  295. }
  296. }
  297. int get_factor_from_table(int rate)
  298. {
  299. int factor;
  300. switch(rate)
  301. {
  302. case 8000:
  303. factor = 4;
  304. break;
  305. case 16000:
  306. factor = 1;
  307. break;
  308. case 32000:
  309. factor = 0;
  310. break;
  311. case 44100:
  312. factor = 13;
  313. break;
  314. case 48000:
  315. factor = 6;
  316. break;
  317. default:
  318. factor = -EFAULT;
  319. break;
  320. }
  321. return factor;
  322. }
  323. void switch_rate(enum audio_type type, int rate)
  324. {
  325. int reg, factor;
  326. factor = get_factor_from_table(rate);
  327. if (factor < 0)
  328. {
  329. rt_kprintf( "unsupported sample rate\n");
  330. return;
  331. }
  332. reg = readl(audio_dev.reg_base + ACW_DIG_IF_CTRL);
  333. if (capture == type)
  334. {
  335. rt_kprintf("capture rate set to %d\n", rate);
  336. reg = reg & (~(0xf<<0));
  337. writel(reg, audio_dev.reg_base + ACW_DIG_IF_CTRL);/*adc and dac sample rate*/
  338. reg = reg | (factor<<0);
  339. writel(reg,audio_dev.reg_base + ACW_DIG_IF_CTRL);
  340. }
  341. else
  342. {
  343. rt_kprintf("playback rate set to %d\n", rate);
  344. reg = reg & (~(0xf<<8));
  345. writel(reg, audio_dev.reg_base + ACW_DIG_IF_CTRL);/*adc and dac sample rate*/
  346. reg = reg | (factor<<8);
  347. writel(reg, audio_dev.reg_base + ACW_DIG_IF_CTRL);
  348. }
  349. }
  350. int get_param_from_volume(int volume)
  351. {
  352. if(volume < 0)
  353. volume = 0;
  354. else if(volume > 100)
  355. volume = 100;
  356. volume = volume * 63 / 100;
  357. return volume;
  358. }
  359. void switch_input_volume(int volume)
  360. {
  361. int reg, param;
  362. param = get_param_from_volume(volume);
  363. if (param < 0)
  364. {
  365. rt_kprintf("capture volume error\n");
  366. return;
  367. }
  368. reg = readl(audio_dev.reg_base + ACW_ADC_PATH_CTRL);
  369. reg = reg & (~(0x3f<<8));
  370. writel(reg, audio_dev.reg_base + ACW_ADC_PATH_CTRL);
  371. reg = reg | (param<<8);
  372. writel(reg,audio_dev.reg_base + ACW_ADC_PATH_CTRL);
  373. }
  374. void init_audio(enum audio_type type,struct fh_audio_cfg *audio_config)
  375. {
  376. int reg;
  377. reg = readl(audio_dev.reg_base + ACW_CTRL);
  378. if ((reg & 0x80000000) == 0)
  379. {
  380. writel(0x80000000, audio_dev.reg_base + ACW_CTRL);/*enable audio*/
  381. }
  382. reg = readl(audio_dev.reg_base + ACW_MISC_CTRL);
  383. if (0x40400 != reg)
  384. {
  385. writel(0x40400,audio_dev.reg_base + ACW_MISC_CTRL);/*misc ctl*/
  386. }
  387. if (capture == type)
  388. {
  389. writel(0x61141b06,audio_dev.reg_base + ACW_ADC_PATH_CTRL);/*adc cfg*/
  390. writel(0x167f2307, audio_dev.reg_base + ACW_ADC_ALC_CTRL);/*adc alc*/
  391. writel(0, audio_dev.reg_base + ACW_RXFIFO_CTRL);/*rx fifo disable*/
  392. switch_input_volume(audio_config->capture.cfg.volume);
  393. switch_rate(capture, audio_config->capture.cfg.rate);
  394. switch_io_type(capture, audio_config->capture.cfg.io_type);
  395. }
  396. else
  397. {
  398. writel(0x3b403f09, audio_dev.reg_base + ACW_DAC_PATH_CTRL);/*dac cfg*/
  399. writel(0, audio_dev.reg_base + ACW_TXFIFO_CTRL);/*tx fifo disable*/
  400. switch_rate(playback, audio_config->playback.cfg.rate);
  401. switch_io_type(playback, audio_config->playback.cfg.io_type);
  402. }
  403. }
  404. static inline long bytes_to_frames(int frame_bit, int bytes)
  405. {
  406. return bytes * 8 /frame_bit;
  407. }
  408. static inline long frames_to_bytes(int frame_bit, int frames)
  409. {
  410. return frames * frame_bit / 8;
  411. }
  412. int avail_data_len(enum audio_type type,struct fh_audio_cfg *stream)
  413. {
  414. int delta;
  415. if (capture == type)
  416. {
  417. delta = stream->capture.hw_ptr - stream->capture.appl_ptr;
  418. if (delta < 0)
  419. {
  420. delta += stream->capture.size;
  421. }
  422. return delta;
  423. }
  424. else
  425. {
  426. delta = stream->playback.appl_ptr - stream->playback.hw_ptr;
  427. if (delta < 0)
  428. {
  429. delta += stream->playback.size;
  430. }
  431. return stream->playback.size - delta;
  432. }
  433. }
  434. static rt_err_t fh_audio_close(rt_device_t dev)
  435. {
  436. struct fh_audio_cfg *audio_config = dev->user_data;
  437. unsigned int reg;
  438. //disable interrupts
  439. reg = readl(audio_dev.reg_base + ACW_CTRL);
  440. reg &= ~(0x3ff);
  441. writel(reg, audio_dev.reg_base + ACW_CTRL);
  442. fh_acw_stop_playback(audio_config);
  443. fh_acw_stop_capture(audio_config);
  444. }
  445. int register_tx_dma(struct fh_audio_cfg *audio_config)
  446. {
  447. int ret;
  448. struct dma_transfer *playback_trans;
  449. playback_trans = audio_config->plauback_trans;
  450. struct rt_dma_device *rt_dma_dev;
  451. rt_dma_dev = audio_config->playback_dma;
  452. if ((audio_config->playback.cfg.buffer_bytes < audio_config->playback.cfg.period_bytes) ||
  453. (audio_config->playback.cfg.buffer_bytes <= 0) || (audio_config->playback.cfg.period_bytes <= 0))
  454. {
  455. rt_kprintf( "buffer_size and period_size are invalid\n");
  456. return RT_ERROR;
  457. }
  458. if(playback_trans->channel_number == ACW_PLY_DMA_CHAN){
  459. ret = rt_dma_dev->ops->control(rt_dma_dev,RT_DEVICE_CTRL_DMA_CYCLIC_PREPARE,playback_trans);
  460. if(ret){
  461. rt_kprintf("can't playback cyclic prepare \n");
  462. return RT_ERROR;
  463. }
  464. ret = rt_dma_dev->ops->control(rt_dma_dev,RT_DEVICE_CTRL_DMA_CYCLIC_START,playback_trans);
  465. if(ret){
  466. rt_kprintf("can't playback cyclic start \n");
  467. return RT_ERROR;
  468. }
  469. }
  470. else
  471. return RT_ERROR;
  472. return 0;
  473. }
  474. int register_rx_dma( struct fh_audio_cfg *audio_config)
  475. {
  476. int ret;
  477. struct dma_transfer *capture_slave;
  478. capture_slave = audio_config->capture_trans;
  479. struct rt_dma_device *rt_dma_dev;
  480. rt_dma_dev = audio_config->capture_dma;
  481. if (!capture_slave)
  482. {
  483. return -ENOMEM;
  484. }
  485. if ((audio_config->capture.cfg.buffer_bytes < audio_config->capture.cfg.period_bytes) ||
  486. (audio_config->capture.cfg.buffer_bytes <= 0) ||(audio_config->capture.cfg.period_bytes <= 0) )
  487. {
  488. rt_kprintf( "buffer_size and period_size are invalid\n");
  489. return RT_ERROR;
  490. }
  491. if(capture_slave->channel_number==ACW_CAP_DMA_CHAN){
  492. ret = rt_dma_dev->ops->control(rt_dma_dev,RT_DEVICE_CTRL_DMA_CYCLIC_PREPARE,capture_slave);
  493. if(ret){
  494. rt_kprintf("can't capture cyclic prepare \n");
  495. return RT_ERROR;
  496. }
  497. ret = rt_dma_dev->ops->control(rt_dma_dev,RT_DEVICE_CTRL_DMA_CYCLIC_START,capture_slave);
  498. if(ret){
  499. rt_kprintf("can't capture cyclic start \n");
  500. return RT_ERROR;
  501. }
  502. }
  503. else
  504. return RT_ERROR;
  505. writel(0x11,audio_dev.reg_base + ACW_RXFIFO_CTRL);//clear rx fifo
  506. writel(0x30029,audio_dev.reg_base + ACW_RXFIFO_CTRL);/*enable rx fifo*/
  507. return 0;
  508. }
  509. void playback_start_wq_handler(struct work_struct *work)
  510. {
  511. int avail;
  512. unsigned int rx_status;
  513. while(1)
  514. {
  515. if (stopping == audio_dev.audio_config->playback.state)
  516. {
  517. return;
  518. }
  519. avail = avail_data_len(playback, audio_dev.audio_config);
  520. if (avail < audio_dev.audio_config->playback.cfg.period_bytes)
  521. {
  522. rt_thread_sleep(0);
  523. }
  524. else
  525. {
  526. rx_status = readl( audio_dev.reg_base + ACW_TXFIFO_CTRL);//clear rx fifo
  527. rx_status = rx_status|(1<<4);
  528. writel(rx_status,audio_dev.reg_base + ACW_TXFIFO_CTRL);
  529. writel(0x30029, audio_dev.reg_base + ACW_TXFIFO_CTRL);
  530. break;
  531. }
  532. }
  533. }
  534. int fh_acw_start_playback(struct fh_audio_cfg *audio_config)
  535. {
  536. int ret;
  537. if(audio_config->playback.state == running)
  538. {
  539. rt_kprintf("playback is running \n");
  540. return 0;
  541. }
  542. if (audio_config->playback.cfg.buffer_bytes >= AUDIO_DMA_PREALLOC_SIZE)
  543. {
  544. rt_kprintf("DMA prealloc buffer is smaller than audio_config->buffer_bytes %x\n",audio_config->playback.cfg.buffer_bytes);
  545. return -ENOMEM;
  546. }
  547. reset_dma_buff(playback,audio_config);
  548. rt_memset(audio_config->playback.area, 0, audio_config->playback.cfg.buffer_bytes);
  549. audio_config->playback.size = audio_config->playback.cfg.buffer_bytes;
  550. audio_config->playback.state = running;
  551. ret = audio_request_playback_channel(audio_config);
  552. if(ret){
  553. rt_kprintf("can't request playback channel\n");
  554. return ret;
  555. }
  556. ret = register_tx_dma(audio_config);
  557. if (ret < 0)
  558. {
  559. rt_kprintf("can't register tx dma\n");
  560. return ret;
  561. }
  562. rt_list_init(&(playback_wq.list));
  563. playback_wq.work_func = (void *)playback_start_wq_handler;
  564. playback_wq.work_data = RT_NULL;
  565. playback_queue = rt_workqueue_create("play_workqueue",WORK_QUEUE_STACK_SIZE,WORK_QUEUE_PRIORITY);
  566. if(!playback_queue){
  567. rt_kprintf("init work_queue error....\n");
  568. return -1;
  569. }
  570. rt_workqueue_dowork(playback_queue,&playback_wq);
  571. return 0;
  572. }
  573. int fh_acw_start_capture(struct fh_audio_cfg *audio_config)
  574. {
  575. int ret;
  576. if(audio_config->capture.state == running)
  577. {
  578. return 0;
  579. }
  580. if (audio_config->capture.cfg.buffer_bytes >= AUDIO_DMA_PREALLOC_SIZE)
  581. {
  582. rt_kprintf("DMA prealloc buffer is smaller than audio_config->buffer_bytes %x\n",audio_config->capture.cfg.buffer_bytes);
  583. return -ENOMEM;
  584. }
  585. reset_dma_buff(capture,audio_config);
  586. rt_memset(audio_config->capture.area, 0, audio_config->capture.cfg.buffer_bytes);
  587. audio_config->capture.size = audio_config->capture.cfg.buffer_bytes;
  588. audio_config->capture.state = running;
  589. ret = audio_request_capture_channel(audio_config);
  590. if(ret){
  591. rt_kprintf("can't request capture channel \n");
  592. return ret;
  593. }
  594. return register_rx_dma(audio_config);
  595. }
  596. static void fh_acw_rx_dma_done(struct fh_audio_cfg *arg)
  597. {
  598. #if 1
  599. struct fh_audio_cfg *audio_config;
  600. audio_config = arg;
  601. audio_config->capture.hw_ptr += audio_config->capture.cfg.period_bytes;
  602. if (audio_config->capture.hw_ptr > audio_config->capture.size ) // TBD_WAIT ...
  603. {
  604. audio_config->capture.hw_ptr = audio_config->capture.hw_ptr - audio_config->capture.size;
  605. }
  606. int avail = avail_data_len(capture,audio_config);
  607. if (avail > audio_config->capture.cfg.period_bytes)
  608. {
  609. rt_sem_release(&audio_config->sem_capture);
  610. }
  611. #endif
  612. }
  613. static void fh_acw_tx_dma_done(void *arg)
  614. {
  615. #if 1
  616. struct fh_audio_cfg *audio_config;
  617. audio_config = ( struct fh_audio_cfg *)arg;
  618. audio_config->playback.hw_ptr += audio_config->playback.cfg.period_bytes;
  619. if (audio_config->playback.hw_ptr > audio_config->playback.size )
  620. {
  621. audio_config->playback.hw_ptr = audio_config->playback.hw_ptr - audio_config->playback.size;
  622. }
  623. int avail = avail_data_len(playback,audio_config);
  624. if (avail > audio_config->playback.cfg.period_bytes)
  625. {
  626. rt_sem_release(&audio_config->sem_playback);
  627. }
  628. #endif
  629. }
  630. bool fh_acw_dma_chan_filter(struct dma_chan *chan, void *filter_param)
  631. {
  632. }
  633. int arg_config_support(struct fh_audio_cfg_arg * cfg)
  634. {
  635. int ret;
  636. ret = get_param_from_volume(cfg->volume);
  637. if (ret < 0) {
  638. rt_kprintf("invalid volume\n");
  639. return -EINVAL;
  640. }
  641. ret = get_factor_from_table(cfg->rate);
  642. if (ret < 0) {
  643. rt_kprintf("invalid rate\n");
  644. return -EINVAL;
  645. }
  646. return 0;
  647. }
  648. void reset_dma_buff(enum audio_type type, struct fh_audio_cfg *audio_config)
  649. {
  650. if (capture == type)
  651. {
  652. audio_config->capture.appl_ptr = 0;
  653. audio_config->capture.hw_ptr = 0;
  654. }
  655. else
  656. {
  657. audio_config->playback.appl_ptr = 0;
  658. audio_config->playback.hw_ptr = 0;
  659. }
  660. }
  661. static rt_err_t fh_audio_ioctl(rt_device_t dev, int cmd, void *arg)
  662. {
  663. struct fh_audio_cfg_arg *cfg;
  664. struct fh_audio_cfg *audio_config = (struct fh_audio_cfg *)dev->user_data;
  665. int ret;
  666. int reg;
  667. int value,pid;
  668. int *p = (int *)arg;
  669. int rx_status,tx_status;
  670. switch (cmd)
  671. {
  672. case AC_INIT_CAPTURE_MEM:
  673. cfg = (struct fh_audio_cfg_arg *)arg;
  674. if (0 == arg_config_support(cfg))
  675. {
  676. audio_config->capture.cfg.io_type = cfg->io_type;
  677. audio_config->capture.cfg.volume = cfg->volume;
  678. audio_config->capture.cfg.rate = cfg->rate;
  679. audio_config->capture.cfg.channels = cfg->channels;
  680. audio_config->capture.cfg.buffer_size = cfg->buffer_size;
  681. audio_config->capture.cfg.frame_bit = FIX_SAMPLE_BIT;
  682. audio_config->capture.cfg.period_size = cfg->period_size;
  683. audio_config->capture.cfg.buffer_bytes = frames_to_bytes(audio_config->capture.cfg.frame_bit,audio_config->capture.cfg.buffer_size);
  684. audio_config->capture.cfg.period_bytes = frames_to_bytes(audio_config->capture.cfg.frame_bit,audio_config->capture.cfg.period_size);
  685. audio_config->capture.cfg.start_threshold =audio_config->capture.cfg.buffer_bytes;
  686. audio_config->capture.cfg.stop_threshold = audio_config->capture.cfg.buffer_bytes;
  687. audio_prealloc_dma_buffer((int)cfg->io_type,audio_config);
  688. reset_dma_buff(capture, audio_config);
  689. rt_mutex_init(&audio_config->capture.lock, "audio_c", RT_IPC_FLAG_PRIO);
  690. init_audio(capture, audio_config);
  691. audio_param_store.input_io_type = audio_config->capture.cfg.io_type;
  692. audio_param_store.input_volume = audio_config->capture.cfg.volume;
  693. }
  694. else
  695. {
  696. return -EINVAL;
  697. }
  698. break;
  699. case AC_INIT_PLAYBACK_MEM:
  700. cfg = arg;
  701. if (0 == arg_config_support(cfg))
  702. {
  703. audio_config->playback.cfg.io_type = cfg->io_type;
  704. audio_config->playback.cfg.volume = cfg->volume;
  705. audio_config->playback.cfg.rate = cfg->rate;
  706. audio_config->playback.cfg.channels = cfg->channels;
  707. audio_config->playback.cfg.buffer_size = cfg->buffer_size;
  708. audio_config->playback.cfg.frame_bit = FIX_SAMPLE_BIT;
  709. audio_config->playback.cfg.period_size = cfg->period_size;
  710. audio_config->playback.cfg.buffer_bytes = frames_to_bytes(audio_config->playback.cfg.frame_bit,audio_config->playback.cfg.buffer_size);
  711. audio_config->playback.cfg.period_bytes = frames_to_bytes(audio_config->playback.cfg.frame_bit,audio_config->playback.cfg.period_size);
  712. audio_config->playback.cfg.start_threshold =audio_config->playback.cfg.buffer_bytes;
  713. audio_config->playback.cfg.stop_threshold = audio_config->playback.cfg.buffer_bytes;
  714. audio_prealloc_dma_buffer((int)cfg->io_type,audio_config); // TBD_WAIT ...
  715. reset_dma_buff(playback, audio_config);
  716. rt_mutex_init(&audio_config->playback.lock, "audio_p", RT_IPC_FLAG_PRIO);
  717. init_audio(playback, audio_config);
  718. }
  719. else
  720. {
  721. return -EINVAL;
  722. }
  723. break;
  724. case AC_AI_EN:
  725. return fh_acw_start_capture(audio_config);
  726. case AC_AO_EN:
  727. rt_kprintf("ao en \n");
  728. return fh_acw_start_playback(audio_config);
  729. case AC_SET_VOL:
  730. value = *(rt_uint32_t *)arg;
  731. ret = get_param_from_volume(value);
  732. if (ret < 0) {
  733. return -EINVAL;
  734. }
  735. audio_param_store.input_volume = value;
  736. switch_input_volume(audio_param_store.input_volume);
  737. break;
  738. case AC_SET_INPUT_MODE:
  739. value = *(rt_uint32_t *)arg;
  740. if (value != mic_in && value != line_in) {
  741. return -EINVAL;
  742. }
  743. audio_param_store.input_io_type = value;
  744. switch_io_type(capture, audio_param_store.input_io_type);
  745. break;
  746. case AC_SET_OUTPUT_MODE:
  747. value = *(rt_uint32_t *)arg;
  748. if (value != speaker_out && value != line_out) {
  749. return -EINVAL;
  750. }
  751. switch_io_type(playback, value);
  752. break;
  753. case AC_AI_DISABLE:
  754. rt_kprintf(" AC_AI_DISABLE\n");
  755. fh_acw_stop_capture(audio_config);
  756. if (audio_config->capture_trans != RT_NULL)
  757. {
  758. rt_free(audio_config->capture_trans);
  759. audio_config->capture_trans = NULL;
  760. }
  761. break;
  762. case AC_AO_DISABLE:
  763. rt_kprintf("[ac_driver]AC_AO_DISABLE\n");
  764. fh_acw_stop_playback(audio_config);
  765. if (audio_config->plauback_trans != RT_NULL)
  766. {
  767. rt_free(audio_config->plauback_trans);
  768. audio_config->plauback_trans = NULL;
  769. }
  770. rt_kprintf(" AC_AO_DISABLE\n");
  771. break;
  772. case AC_AI_PAUSE:
  773. rt_kprintf( "capture pause\n");
  774. rx_status = readl(audio_dev.reg_base + ACW_RXFIFO_CTRL);/*rx fifo disable*/
  775. rx_status = rx_status&(~(1<<0));
  776. writel(rx_status, audio_dev.reg_base + ACW_RXFIFO_CTRL);/*rx fifo disable*/
  777. break;
  778. case AC_AI_RESUME:
  779. rt_kprintf( "capture resume\n");
  780. rx_status = readl( audio_dev.reg_base + ACW_RXFIFO_CTRL);//clear rx fifo
  781. rx_status = rx_status|(1<<4);
  782. writel(rx_status,audio_dev.reg_base+ ACW_RXFIFO_CTRL);/*enable rx fifo*/
  783. rx_status = rx_status&(~(1<<4));
  784. rx_status = rx_status|(1<<0);
  785. writel(rx_status,audio_dev.reg_base + ACW_RXFIFO_CTRL);/*enable rx fifo*/
  786. break;
  787. case AC_AO_PAUSE:
  788. rt_kprintf( "playback pause\n");
  789. tx_status = readl(audio_dev.reg_base + ACW_TXFIFO_CTRL);/*rx fifo disable*/
  790. tx_status = tx_status&(~(1<<0));
  791. writel(tx_status, audio_dev.reg_base + ACW_TXFIFO_CTRL);/*tx fifo disable*/
  792. break;
  793. case AC_AO_RESUME:
  794. rt_kprintf( "playback resume\n");
  795. tx_status = readl( audio_dev.reg_base + ACW_TXFIFO_CTRL);//clear rx fifo
  796. tx_status = tx_status|(1<<0);
  797. writel(tx_status,audio_dev.reg_base + ACW_TXFIFO_CTRL); //enable tx fifo read enable
  798. break;
  799. default:
  800. return -ENOTTY;
  801. }
  802. return 0;
  803. }
  804. static rt_err_t fh_audio_open(rt_device_t dev, rt_uint16_t oflag)
  805. {
  806. unsigned int reg;
  807. struct fh_audio_cfg *audio_config = dev->user_data;
  808. //enable interrupts
  809. reg = readl(audio_dev.reg_base + ACW_CTRL);
  810. reg |= 0xa;
  811. writel(reg, audio_dev.reg_base + ACW_CTRL);
  812. return 0;
  813. }
  814. static rt_err_t fh_audio_tx_poll(rt_device_t dev, void *buffer){
  815. struct fh_audio_cfg *audio_config = dev->user_data;
  816. unsigned int mask = 0;
  817. long avail;
  818. if (running == audio_config->playback.state)
  819. {
  820. rt_sem_take(&audio_config->sem_playback, RT_WAITING_FOREVER);
  821. avail = avail_data_len(playback, audio_config);
  822. if (avail > audio_config->playback.cfg.period_bytes)
  823. {
  824. mask |= POLLOUT | POLLWRNORM;
  825. }
  826. }
  827. return mask;
  828. }
  829. static rt_err_t fh_audio_rx_poll(rt_device_t dev, rt_size_t size){
  830. struct fh_audio_cfg *audio_config = dev->user_data;
  831. unsigned int mask = 0;
  832. long avail;
  833. if (running == audio_config->capture.state)
  834. {
  835. rt_sem_take(&audio_config->sem_capture, RT_WAITING_FOREVER);
  836. avail = avail_data_len(capture, audio_config);
  837. if (avail > audio_config->capture.cfg.period_bytes)
  838. {
  839. mask |= POLLIN | POLLRDNORM;
  840. }
  841. }
  842. return mask;
  843. }
  844. static dma_complete_callback mem_complete(void *p){
  845. struct rt_completion *completion = (struct rt_completion *)p;
  846. rt_completion_done(completion);
  847. }
  848. static rt_size_t fh_audio_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
  849. {
  850. int ret;
  851. struct fh_audio_cfg *audio_config = dev->user_data;
  852. int after,left;
  853. int pid,avail;
  854. avail = avail_data_len(capture, audio_config);
  855. if (avail > size)
  856. {
  857. avail = size;
  858. }
  859. after = avail + audio_config->capture.appl_ptr;
  860. if(after > audio_config->capture.size)
  861. {
  862. left = avail - (audio_config->capture.size - audio_config->capture.appl_ptr);
  863. rt_memcpy(buffer, audio_config->capture.area+audio_config->capture.appl_ptr, audio_config->capture.size-audio_config->capture.appl_ptr);
  864. rt_memcpy(buffer+audio_config->capture.size-audio_config->capture.appl_ptr,audio_config->capture.area,left);
  865. rt_mutex_take(&audio_config->capture.lock, RT_WAITING_FOREVER);
  866. audio_config->capture.appl_ptr = left;
  867. rt_mutex_release(&audio_config->capture.lock);
  868. }
  869. else
  870. {
  871. rt_memcpy(buffer,audio_config->capture.area+audio_config->capture.appl_ptr,avail);
  872. rt_mutex_take(&audio_config->capture.lock, RT_WAITING_FOREVER);
  873. audio_config->capture.appl_ptr += avail;
  874. rt_mutex_release(&audio_config->capture.lock);
  875. }
  876. return avail;
  877. }
  878. static rt_size_t fh_audio_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
  879. {
  880. struct fh_audio_cfg *audio_config = dev->user_data;
  881. int ret;
  882. int after,left;
  883. int pid,avail;
  884. avail = avail_data_len(playback,audio_config);
  885. if (0 == avail)
  886. {
  887. return 0;
  888. }
  889. if (avail > size)
  890. {
  891. avail = size;
  892. }
  893. after = avail+audio_config->playback.appl_ptr;
  894. if(after > audio_config->playback.size)
  895. {
  896. left = avail - (audio_config->playback.size-audio_config->playback.appl_ptr);
  897. rt_memcpy(audio_config->playback.area+audio_config->playback.appl_ptr,buffer,audio_config->playback.size-audio_config->playback.appl_ptr);
  898. rt_memcpy(audio_config->playback.area,buffer+audio_config->playback.size-audio_config->playback.appl_ptr,left);
  899. rt_mutex_take(&audio_config->playback.lock, RT_WAITING_FOREVER);
  900. audio_config->playback.appl_ptr = left;
  901. rt_mutex_release(&audio_config->playback.lock);
  902. }
  903. else
  904. {
  905. rt_memcpy(audio_config->playback.area+audio_config->playback.appl_ptr,buffer,avail);
  906. rt_mutex_take(&audio_config->playback.lock, RT_WAITING_FOREVER);
  907. audio_config->playback.appl_ptr += avail;
  908. rt_mutex_release(&audio_config->playback.lock);
  909. }
  910. return avail;
  911. }
  912. static void fh_audio_interrupt(int irq, void *param)
  913. {
  914. unsigned int interrupts, reg;
  915. struct fh_audio_cfg *audio_config = audio_dev.audio_config;
  916. interrupts = readl(audio_dev.reg_base + ACW_CTRL);
  917. writel(interrupts, audio_dev.reg_base + ACW_CTRL);
  918. if(interrupts & ACW_INTR_RX_UNDERFLOW)
  919. {
  920. fh_acw_stop_capture(audio_config);
  921. fh_acw_start_capture(audio_config);
  922. rt_kprintf("ACW_INTR_RX_UNDERFLOW\n");
  923. }
  924. if(interrupts & ACW_INTR_RX_OVERFLOW)
  925. {
  926. fh_acw_stop_capture(audio_config);
  927. fh_acw_start_capture(audio_config);
  928. rt_kprintf("ACW_INTR_RX_OVERFLOW\n");
  929. }
  930. if(interrupts & ACW_INTR_TX_UNDERFLOW)
  931. {
  932. fh_acw_stop_capture(audio_config);
  933. fh_acw_start_capture(audio_config);
  934. rt_kprintf("ACW_INTR_TX_UNDERFLOW\n");
  935. }
  936. if(interrupts & ACW_INTR_TX_OVERFLOW)
  937. {
  938. fh_acw_stop_capture(audio_config);
  939. fh_acw_start_capture(audio_config);
  940. rt_kprintf("ACW_INTR_TX_OVERFLOW\n");
  941. }
  942. rt_kprintf("interrupts: 0x%x\n", interrupts);
  943. }
  944. void audio_prealloc_dma_buffer(int aiaotype,struct fh_audio_cfg *audio_config)
  945. {
  946. if(aiaotype == mic_in || aiaotype == line_in){
  947. audio_config->capture.area = (void *)fh_dma_mem_malloc(audio_config->capture.cfg.buffer_bytes \
  948. + audio_config->capture.cfg.period_bytes);
  949. if (!audio_config->capture.area)
  950. {
  951. rt_kprintf("no enough mem for capture buffer alloc\n");
  952. return ;
  953. }
  954. }
  955. if(aiaotype == speaker_out || aiaotype == line_out){
  956. audio_config->playback.area = (void *)fh_dma_mem_malloc(audio_config->playback.cfg.buffer_bytes \
  957. + audio_config->playback.cfg.period_bytes);
  958. if (!audio_config->playback.area)
  959. {
  960. rt_kprintf("no enough mem for playback buffer alloc\n");
  961. return ;
  962. }}
  963. }
  964. void audio_free_prealloc_dma_buffer(struct fh_audio_cfg *audio_config)
  965. {
  966. rt_free( audio_config->capture.area);
  967. rt_free( audio_config->playback.area);
  968. }
  969. static void init_audio_mutex(struct fh_audio_cfg *audio_config)
  970. {
  971. rt_sem_init(&audio_config->sem_capture, "sem_capture", 0, RT_IPC_FLAG_FIFO);
  972. rt_sem_init(&audio_config->sem_playback, "sem_playback", 0, RT_IPC_FLAG_FIFO);
  973. }
  974. int audio_request_capture_channel(struct fh_audio_cfg *audio_config){
  975. struct rt_dma_device *rt_dma_dev;
  976. /*request audio rx dma channel*/
  977. struct dma_transfer *dma_rx_transfer;
  978. int ret;
  979. dma_rx_transfer = rt_malloc(sizeof(struct dma_transfer));
  980. if (!dma_rx_transfer)
  981. {
  982. rt_kprintf("alloc dma_rx_transfer failed\n");
  983. return RT_ENOMEM;
  984. }
  985. rt_memset(dma_rx_transfer, 0, sizeof(struct dma_transfer));
  986. rt_dma_dev = (struct rt_dma_device *)rt_device_find("fh81_dma");
  987. if(rt_dma_dev == RT_NULL){
  988. rt_kprintf("can't find dma dev\n");
  989. return -1;
  990. }
  991. audio_config->capture_dma = rt_dma_dev;
  992. audio_config->capture_trans = dma_rx_transfer;
  993. rt_dma_dev->ops->init(rt_dma_dev);
  994. dma_rx_transfer->channel_number = ACW_CAP_DMA_CHAN;
  995. dma_rx_transfer->dma_number = 0;
  996. dma_rx_transfer->dst_add = (rt_uint32_t)audio_config->capture.area;//audio_config->capture.area;//(rt_uint32_t)&tx_buff[0];
  997. dma_rx_transfer->dst_inc_mode = DW_DMA_SLAVE_INC;
  998. dma_rx_transfer->dst_msize = DW_DMA_SLAVE_MSIZE_32;
  999. dma_rx_transfer->dst_width = DW_DMA_SLAVE_WIDTH_32BIT;
  1000. dma_rx_transfer->fc_mode = DMA_P2M;
  1001. dma_rx_transfer->src_add = (rt_uint32_t)ACW_RXFIFO;
  1002. dma_rx_transfer->src_inc_mode = DW_DMA_SLAVE_FIX;
  1003. dma_rx_transfer->src_msize = DW_DMA_SLAVE_MSIZE_32;
  1004. dma_rx_transfer->src_hs = DMA_HW_HANDSHAKING;
  1005. dma_rx_transfer->src_width = DW_DMA_SLAVE_WIDTH_32BIT;
  1006. dma_rx_transfer->trans_len = (audio_config->capture.cfg.buffer_bytes / 4); // DW_DMA_SLAVE_WIDTH_32BIT BUFF_SIZE;
  1007. dma_rx_transfer->src_per =ACODEC_RX;
  1008. dma_rx_transfer->period_len = audio_config->capture.cfg.period_bytes / 4;// (audio_config->capture.cfg.period_bytes / 4); // TEST_PER_NO;
  1009. dma_rx_transfer->complete_callback =(dma_complete_callback)fh_acw_rx_dma_done;
  1010. dma_rx_transfer->complete_para = audio_config;
  1011. rt_dma_dev->ops->control(rt_dma_dev,RT_DEVICE_CTRL_DMA_OPEN,dma_rx_transfer);
  1012. ret = rt_dma_dev->ops->control(rt_dma_dev,RT_DEVICE_CTRL_DMA_REQUEST_CHANNEL,dma_rx_transfer);
  1013. if(ret){
  1014. rt_kprintf("can't request capture channel\n");
  1015. dma_rx_transfer->channel_number =0xff;
  1016. return -ret;
  1017. }
  1018. }
  1019. int audio_request_playback_channel(struct fh_audio_cfg *audio_config)
  1020. {
  1021. struct rt_dma_device *rt_dma_dev;
  1022. int ret;
  1023. struct dma_transfer *dma_tx_transfer;
  1024. dma_tx_transfer = rt_malloc(sizeof(struct dma_transfer));
  1025. if (!dma_tx_transfer)
  1026. {
  1027. rt_kprintf("alloc dma_tx_transfer failed\n");
  1028. return RT_ENOMEM;
  1029. }
  1030. audio_config->plauback_trans = dma_tx_transfer;
  1031. rt_dma_dev = (struct rt_dma_device *)rt_device_find("fh81_dma");
  1032. if(rt_dma_dev == RT_NULL){
  1033. rt_kprintf("can't find dma dev\n");
  1034. return -1;
  1035. }
  1036. rt_dma_dev->ops->init(rt_dma_dev);
  1037. audio_config->playback_dma = rt_dma_dev;
  1038. rt_memset(dma_tx_transfer, 0, sizeof(struct dma_transfer));
  1039. dma_tx_transfer->channel_number = ACW_PLY_DMA_CHAN;
  1040. dma_tx_transfer->dma_number = 0;
  1041. dma_tx_transfer->dst_add = (rt_uint32_t)ACW_TXFIFO;
  1042. dma_tx_transfer->dst_hs = DMA_HW_HANDSHAKING;
  1043. dma_tx_transfer->dst_inc_mode = DW_DMA_SLAVE_FIX;
  1044. dma_tx_transfer->dst_msize = DW_DMA_SLAVE_MSIZE_32;
  1045. dma_tx_transfer->dst_per = ACODEC_TX;
  1046. dma_tx_transfer->dst_width = DW_DMA_SLAVE_WIDTH_32BIT;
  1047. dma_tx_transfer->fc_mode = DMA_M2P;
  1048. dma_tx_transfer->src_add = (rt_uint32_t)audio_config->playback.area;
  1049. dma_tx_transfer->src_inc_mode = DW_DMA_SLAVE_INC;
  1050. dma_tx_transfer->src_msize = DW_DMA_SLAVE_MSIZE_32;
  1051. dma_tx_transfer->src_width = DW_DMA_SLAVE_WIDTH_32BIT;
  1052. dma_tx_transfer->trans_len = (audio_config->playback.cfg.buffer_bytes / 4);// BUFF_SIZE;
  1053. dma_tx_transfer->period_len = (audio_config->playback.cfg.period_bytes / 4); // TEST_PER_NO;
  1054. dma_tx_transfer->complete_callback =(dma_complete_callback)fh_acw_tx_dma_done;
  1055. dma_tx_transfer->complete_para = audio_config;
  1056. rt_dma_dev->ops->control(rt_dma_dev,RT_DEVICE_CTRL_DMA_OPEN,dma_tx_transfer);
  1057. ret = rt_dma_dev->ops->control(rt_dma_dev,RT_DEVICE_CTRL_DMA_REQUEST_CHANNEL,dma_tx_transfer);
  1058. if(ret){
  1059. rt_kprintf("can't request playbak channel\n");
  1060. dma_tx_transfer->channel_number = 0xff;
  1061. return -ret;
  1062. }
  1063. return 0;
  1064. }
  1065. void audio_release_dma_channel(struct fh_audio_cfg *audio_config)
  1066. {
  1067. if (audio_config->plauback_trans != RT_NULL)
  1068. {
  1069. audio_config->playback_dma->ops->control(audio_config->playback_dma,RT_DEVICE_CTRL_DMA_RELEASE_CHANNEL,audio_config->plauback_trans);
  1070. rt_free(audio_config->plauback_trans);
  1071. audio_config->plauback_trans = NULL;
  1072. }
  1073. if (audio_config->capture_trans != RT_NULL)
  1074. {
  1075. audio_config->capture_dma->ops->control(audio_config->capture_dma,RT_DEVICE_CTRL_DMA_RELEASE_CHANNEL,audio_config->capture_trans);
  1076. rt_free(audio_config->capture_trans);
  1077. audio_config->capture_trans = NULL;
  1078. }
  1079. }
  1080. void fh_audio_init(void)
  1081. {
  1082. struct fh_audio_cfg *audio_config;
  1083. audio_config = rt_malloc(sizeof(struct fh_audio_cfg));
  1084. memset(audio_config,0,sizeof(struct fh_audio_cfg)); // new add
  1085. audio_dev.reg_base = 0xf0a00000;
  1086. init_audio_mutex(audio_config);
  1087. rt_device_t audio ;
  1088. audio = rt_malloc(sizeof(struct rt_device));
  1089. if (audio == RT_NULL){
  1090. rt_kprintf("%s no mem \n",__func__);
  1091. }
  1092. audio->user_data = audio_config;
  1093. audio->open =fh_audio_open;
  1094. audio->read = fh_audio_read;
  1095. audio->write = fh_audio_write;
  1096. audio->close = fh_audio_close;
  1097. audio->control = fh_audio_ioctl;
  1098. audio->rx_indicate =fh_audio_rx_poll;
  1099. audio->tx_complete=fh_audio_tx_poll;
  1100. audio_dev.audio_config = audio_config; // TBD_WAIT 2015.09.17 add
  1101. rt_device_register(audio, "audio", RT_DEVICE_FLAG_RDWR);
  1102. }
  1103. #if ACW_SELFTEST
  1104. #define TEST_FN "/audio.dat"
  1105. static rt_uint32_t rx_buff[BUFF_SIZE] __attribute__((aligned(32))) ;
  1106. static const rt_uint32_t tx_buff[BUFF_SIZE*2] __attribute__((aligned(32)))= {
  1107. 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,
  1108. 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,
  1109. 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,
  1110. 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,
  1111. 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,
  1112. };
  1113. struct fh_audio_cfg_arg cfg;
  1114. void fh_acw_test(){
  1115. rt_device_t acw_dev ;
  1116. int i;
  1117. int output=3;
  1118. int select;
  1119. int select_rx_status =0;
  1120. int select_tx_status =0;
  1121. int fd;
  1122. int index, length;
  1123. int mic_boost=1;
  1124. int ret;
  1125. acw_dev = ( rt_device_t )rt_device_find("audio");
  1126. for(i=0;i<BUFF_SIZE;i++)
  1127. rx_buff[i] = i*0x500;
  1128. acw_dev->open(acw_dev,0);
  1129. cfg.buffer_size = BUFF_SIZE;
  1130. cfg.channels =0;
  1131. cfg.frame_bit = 16;
  1132. cfg.io_type = mic_in;
  1133. cfg.period_size = BUFF_SIZE/8;
  1134. cfg.rate = 8000;
  1135. cfg.volume = 80;
  1136. // for(i=0;i<100;i++){
  1137. // acw_dev->control(acw_dev,AC_INIT_CAPTURE_MEM,&cfg);
  1138. //
  1139. // acw_dev->control(acw_dev,AC_AI_EN,&cfg);
  1140. // cfg.io_type = line_out;
  1141. // acw_dev->control(acw_dev,AC_INIT_PLAYBACK_MEM,&cfg);
  1142. // acw_dev->control(acw_dev,AC_AO_EN,&cfg);
  1143. // acw_dev->control(acw_dev,AC_SET_OUTPUT_MODE,&output);
  1144. // acw_dev->control(acw_dev,AC_AI_DISABLE,&cfg);
  1145. //
  1146. // acw_dev->control(acw_dev,AC_AO_DISABLE,&cfg);
  1147. // rt_kprintf(" %d \n",i);
  1148. // }
  1149. cfg.io_type = mic_in;
  1150. acw_dev->control(acw_dev,AC_INIT_CAPTURE_MEM,&cfg);
  1151. ret = acw_dev->control(acw_dev,AC_AI_EN,&cfg);
  1152. if(ret)
  1153. acw_dev->control(acw_dev,AC_AI_DISABLE,&cfg);
  1154. cfg.io_type = line_out;
  1155. acw_dev->control(acw_dev,AC_INIT_PLAYBACK_MEM,&cfg);
  1156. ret = acw_dev->control(acw_dev,AC_AO_EN,&cfg);
  1157. if(ret){
  1158. acw_dev->control(acw_dev,AC_AO_DISABLE,&cfg);
  1159. // acw_dev->control(acw_dev,AC_SET_OUTPUT_MODE,&output);
  1160. return ;
  1161. }
  1162. for(i=0;i<100;i++)
  1163. {
  1164. rx:
  1165. select = acw_dev->rx_indicate(acw_dev,RT_NULL);
  1166. if(!select)
  1167. goto rx;
  1168. acw_dev->read(acw_dev,0,&rx_buff[0],1024*8);
  1169. tx:
  1170. select = acw_dev->tx_complete(acw_dev , RT_NULL);
  1171. if(!select)
  1172. goto tx;
  1173. acw_dev->write(acw_dev,0,&rx_buff[0],1024*8);
  1174. }
  1175. acw_dev->close(acw_dev);
  1176. }
  1177. #ifdef RT_USING_FINSH
  1178. #include <finsh.h>
  1179. FINSH_FUNCTION_EXPORT(fh_acw_test, fh_acw_test);
  1180. #endif
  1181. #endif
  1182. #endif