harmony.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993
  1. /* Hewlett-Packard Harmony audio driver
  2. *
  3. * This is a driver for the Harmony audio chipset found
  4. * on the LASI ASIC of various early HP PA-RISC workstations.
  5. *
  6. * Copyright (C) 2004, Kyle McMartin <kyle@{debian.org,parisc-linux.org}>
  7. *
  8. * Based on the previous Harmony incarnations by,
  9. * Copyright 2000 (c) Linuxcare Canada, Alex deVries
  10. * Copyright 2000-2003 (c) Helge Deller
  11. * Copyright 2001 (c) Matthieu Delahaye
  12. * Copyright 2001 (c) Jean-Christophe Vaugeois
  13. * Copyright 2003 (c) Laurent Canet
  14. * Copyright 2004 (c) Stuart Brady
  15. *
  16. * This program is free software; you can redistribute it and/or modify
  17. * it under the terms of the GNU General Public License, version 2, as
  18. * published by the Free Software Foundation.
  19. *
  20. * This program is distributed in the hope that it will be useful,
  21. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23. * GNU General Public License for more details.
  24. *
  25. * You should have received a copy of the GNU General Public License
  26. * along with this program; if not, write to the Free Software
  27. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  28. *
  29. * Notes:
  30. * - graveyard and silence buffers last for lifetime of
  31. * the driver. playback and capture buffers are allocated
  32. * per _open()/_close().
  33. *
  34. * TODO:
  35. *
  36. */
  37. #include <linux/init.h>
  38. #include <linux/slab.h>
  39. #include <linux/time.h>
  40. #include <linux/wait.h>
  41. #include <linux/delay.h>
  42. #include <linux/module.h>
  43. #include <linux/interrupt.h>
  44. #include <linux/spinlock.h>
  45. #include <linux/dma-mapping.h>
  46. #include <sound/driver.h>
  47. #include <sound/core.h>
  48. #include <sound/pcm.h>
  49. #include <sound/control.h>
  50. #include <sound/rawmidi.h>
  51. #include <sound/initval.h>
  52. #include <sound/info.h>
  53. #include <asm/io.h>
  54. #include <asm/hardware.h>
  55. #include <asm/parisc-device.h>
  56. #include "harmony.h"
  57. static struct parisc_device_id snd_harmony_devtable[] = {
  58. /* bushmaster / flounder */
  59. { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007A },
  60. /* 712 / 715 */
  61. { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007B },
  62. /* pace */
  63. { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007E },
  64. /* outfield / coral II */
  65. { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007F },
  66. { 0, }
  67. };
  68. MODULE_DEVICE_TABLE(parisc, snd_harmony_devtable);
  69. #define NAME "harmony"
  70. #define PFX NAME ": "
  71. static unsigned int snd_harmony_rates[] = {
  72. 5512, 6615, 8000, 9600,
  73. 11025, 16000, 18900, 22050,
  74. 27428, 32000, 33075, 37800,
  75. 44100, 48000
  76. };
  77. static unsigned int rate_bits[14] = {
  78. HARMONY_SR_5KHZ, HARMONY_SR_6KHZ, HARMONY_SR_8KHZ,
  79. HARMONY_SR_9KHZ, HARMONY_SR_11KHZ, HARMONY_SR_16KHZ,
  80. HARMONY_SR_18KHZ, HARMONY_SR_22KHZ, HARMONY_SR_27KHZ,
  81. HARMONY_SR_32KHZ, HARMONY_SR_33KHZ, HARMONY_SR_37KHZ,
  82. HARMONY_SR_44KHZ, HARMONY_SR_48KHZ
  83. };
  84. static snd_pcm_hw_constraint_list_t hw_constraint_rates = {
  85. .count = ARRAY_SIZE(snd_harmony_rates),
  86. .list = snd_harmony_rates,
  87. .mask = 0,
  88. };
  89. inline unsigned long
  90. harmony_read(harmony_t *h, unsigned r)
  91. {
  92. return __raw_readl(h->iobase + r);
  93. }
  94. inline void
  95. harmony_write(harmony_t *h, unsigned r, unsigned long v)
  96. {
  97. __raw_writel(v, h->iobase + r);
  98. }
  99. static void
  100. harmony_wait_for_control(harmony_t *h)
  101. {
  102. while (harmony_read(h, HARMONY_CNTL) & HARMONY_CNTL_C) ;
  103. }
  104. inline void
  105. harmony_reset(harmony_t *h)
  106. {
  107. harmony_write(h, HARMONY_RESET, 1);
  108. mdelay(50);
  109. harmony_write(h, HARMONY_RESET, 0);
  110. }
  111. static void
  112. harmony_disable_interrupts(harmony_t *h)
  113. {
  114. u32 dstatus;
  115. harmony_wait_for_control(h);
  116. dstatus = harmony_read(h, HARMONY_DSTATUS);
  117. dstatus &= ~HARMONY_DSTATUS_IE;
  118. harmony_write(h, HARMONY_DSTATUS, dstatus);
  119. }
  120. static void
  121. harmony_enable_interrupts(harmony_t *h)
  122. {
  123. u32 dstatus;
  124. harmony_wait_for_control(h);
  125. dstatus = harmony_read(h, HARMONY_DSTATUS);
  126. dstatus |= HARMONY_DSTATUS_IE;
  127. harmony_write(h, HARMONY_DSTATUS, dstatus);
  128. }
  129. static void
  130. harmony_mute(harmony_t *h)
  131. {
  132. unsigned long flags;
  133. spin_lock_irqsave(&h->mixer_lock, flags);
  134. harmony_wait_for_control(h);
  135. harmony_write(h, HARMONY_GAINCTL, HARMONY_GAIN_SILENCE);
  136. spin_unlock_irqrestore(&h->mixer_lock, flags);
  137. }
  138. static void
  139. harmony_unmute(harmony_t *h)
  140. {
  141. unsigned long flags;
  142. spin_lock_irqsave(&h->mixer_lock, flags);
  143. harmony_wait_for_control(h);
  144. harmony_write(h, HARMONY_GAINCTL, h->st.gain);
  145. spin_unlock_irqrestore(&h->mixer_lock, flags);
  146. }
  147. static void
  148. harmony_set_control(harmony_t *h)
  149. {
  150. u32 ctrl;
  151. unsigned long flags;
  152. spin_lock_irqsave(&h->lock, flags);
  153. ctrl = (HARMONY_CNTL_C |
  154. (h->st.format << 6) |
  155. (h->st.stereo << 5) |
  156. (h->st.rate));
  157. harmony_wait_for_control(h);
  158. harmony_write(h, HARMONY_CNTL, ctrl);
  159. spin_unlock_irqrestore(&h->lock, flags);
  160. }
  161. static irqreturn_t
  162. snd_harmony_interrupt(int irq, void *dev, struct pt_regs *regs)
  163. {
  164. u32 dstatus;
  165. harmony_t *h = dev;
  166. spin_lock(&h->lock);
  167. harmony_disable_interrupts(h);
  168. harmony_wait_for_control(h);
  169. dstatus = harmony_read(h, HARMONY_DSTATUS);
  170. spin_unlock(&h->lock);
  171. if (dstatus & HARMONY_DSTATUS_PN) {
  172. if (h->psubs) {
  173. spin_lock(&h->lock);
  174. h->pbuf.buf += h->pbuf.count; /* PAGE_SIZE */
  175. h->pbuf.buf %= h->pbuf.size; /* MAX_BUFS*PAGE_SIZE */
  176. harmony_write(h, HARMONY_PNXTADD,
  177. h->pbuf.addr + h->pbuf.buf);
  178. h->stats.play_intr++;
  179. spin_unlock(&h->lock);
  180. snd_pcm_period_elapsed(h->psubs);
  181. } else {
  182. spin_lock(&h->lock);
  183. harmony_write(h, HARMONY_PNXTADD, h->sdma.addr);
  184. h->stats.silence_intr++;
  185. spin_unlock(&h->lock);
  186. }
  187. }
  188. if (dstatus & HARMONY_DSTATUS_RN) {
  189. if (h->csubs) {
  190. spin_lock(&h->lock);
  191. h->cbuf.buf += h->cbuf.count;
  192. h->cbuf.buf %= h->cbuf.size;
  193. harmony_write(h, HARMONY_RNXTADD,
  194. h->cbuf.addr + h->cbuf.buf);
  195. h->stats.rec_intr++;
  196. spin_unlock(&h->lock);
  197. snd_pcm_period_elapsed(h->csubs);
  198. } else {
  199. spin_lock(&h->lock);
  200. harmony_write(h, HARMONY_RNXTADD, h->gdma.addr);
  201. h->stats.graveyard_intr++;
  202. spin_unlock(&h->lock);
  203. }
  204. }
  205. spin_lock(&h->lock);
  206. harmony_enable_interrupts(h);
  207. spin_unlock(&h->lock);
  208. return IRQ_HANDLED;
  209. }
  210. static unsigned int
  211. snd_harmony_rate_bits(int rate)
  212. {
  213. unsigned int i;
  214. for (i = 0; i < ARRAY_SIZE(snd_harmony_rates); i++)
  215. if (snd_harmony_rates[i] == rate)
  216. return rate_bits[i];
  217. return HARMONY_SR_44KHZ;
  218. }
  219. static snd_pcm_hardware_t snd_harmony_playback =
  220. {
  221. .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
  222. SNDRV_PCM_INFO_JOINT_DUPLEX | SNDRV_PCM_INFO_MMAP_VALID |
  223. SNDRV_PCM_INFO_BLOCK_TRANSFER),
  224. .formats = (SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_MU_LAW |
  225. SNDRV_PCM_FMTBIT_A_LAW),
  226. .rates = (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_48000 |
  227. SNDRV_PCM_RATE_KNOT),
  228. .rate_min = 5512,
  229. .rate_max = 48000,
  230. .channels_min = 1,
  231. .channels_max = 2,
  232. .buffer_bytes_max = MAX_BUF_SIZE,
  233. .period_bytes_min = BUF_SIZE,
  234. .period_bytes_max = BUF_SIZE,
  235. .periods_min = 1,
  236. .periods_max = MAX_BUFS,
  237. .fifo_size = 0,
  238. };
  239. static snd_pcm_hardware_t snd_harmony_capture =
  240. {
  241. .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
  242. SNDRV_PCM_INFO_JOINT_DUPLEX | SNDRV_PCM_INFO_MMAP_VALID |
  243. SNDRV_PCM_INFO_BLOCK_TRANSFER),
  244. .formats = (SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_MU_LAW |
  245. SNDRV_PCM_FMTBIT_A_LAW),
  246. .rates = (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_48000 |
  247. SNDRV_PCM_RATE_KNOT),
  248. .rate_min = 5512,
  249. .rate_max = 48000,
  250. .channels_min = 1,
  251. .channels_max = 2,
  252. .buffer_bytes_max = MAX_BUF_SIZE,
  253. .period_bytes_min = BUF_SIZE,
  254. .period_bytes_max = BUF_SIZE,
  255. .periods_min = 1,
  256. .periods_max = MAX_BUFS,
  257. .fifo_size = 0,
  258. };
  259. static int
  260. snd_harmony_playback_trigger(snd_pcm_substream_t *ss, int cmd)
  261. {
  262. harmony_t *h = snd_pcm_substream_chip(ss);
  263. unsigned long flags;
  264. if (h->st.capturing)
  265. return -EBUSY;
  266. spin_lock_irqsave(&h->lock, flags);
  267. switch (cmd) {
  268. case SNDRV_PCM_TRIGGER_START:
  269. h->st.playing = 1;
  270. harmony_write(h, HARMONY_PNXTADD, h->pbuf.addr);
  271. harmony_write(h, HARMONY_RNXTADD, h->gdma.addr);
  272. harmony_unmute(h);
  273. harmony_enable_interrupts(h);
  274. break;
  275. case SNDRV_PCM_TRIGGER_STOP:
  276. h->st.playing = 0;
  277. harmony_mute(h);
  278. harmony_disable_interrupts(h);
  279. break;
  280. case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  281. case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  282. case SNDRV_PCM_TRIGGER_SUSPEND:
  283. default:
  284. spin_unlock_irqrestore(&h->lock, flags);
  285. snd_BUG();
  286. return -EINVAL;
  287. }
  288. spin_unlock_irqrestore(&h->lock, flags);
  289. return 0;
  290. }
  291. static int
  292. snd_harmony_capture_trigger(snd_pcm_substream_t *ss, int cmd)
  293. {
  294. harmony_t *h = snd_pcm_substream_chip(ss);
  295. unsigned long flags;
  296. if (h->st.playing)
  297. return -EBUSY;
  298. spin_lock_irqsave(&h->lock, flags);
  299. switch (cmd) {
  300. case SNDRV_PCM_TRIGGER_START:
  301. h->st.capturing = 1;
  302. harmony_write(h, HARMONY_PNXTADD, h->sdma.addr);
  303. harmony_write(h, HARMONY_RNXTADD, h->cbuf.addr);
  304. harmony_unmute(h);
  305. harmony_enable_interrupts(h);
  306. break;
  307. case SNDRV_PCM_TRIGGER_STOP:
  308. h->st.capturing = 0;
  309. harmony_mute(h);
  310. harmony_disable_interrupts(h);
  311. break;
  312. case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  313. case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  314. case SNDRV_PCM_TRIGGER_SUSPEND:
  315. default:
  316. spin_unlock_irqrestore(&h->lock, flags);
  317. snd_BUG();
  318. return -EINVAL;
  319. }
  320. spin_unlock_irqrestore(&h->lock, flags);
  321. return 0;
  322. }
  323. static int
  324. snd_harmony_set_data_format(harmony_t *h, int fmt, int force)
  325. {
  326. int o = h->st.format;
  327. int n;
  328. switch(fmt) {
  329. case SNDRV_PCM_FORMAT_S16_BE:
  330. n = HARMONY_DF_16BIT_LINEAR;
  331. break;
  332. case SNDRV_PCM_FORMAT_A_LAW:
  333. n = HARMONY_DF_8BIT_ALAW;
  334. break;
  335. case SNDRV_PCM_FORMAT_MU_LAW:
  336. n = HARMONY_DF_8BIT_ULAW;
  337. break;
  338. default:
  339. n = HARMONY_DF_16BIT_LINEAR;
  340. break;
  341. }
  342. if (force || o != n) {
  343. snd_pcm_format_set_silence(fmt, h->sdma.area, SILENCE_BUFSZ /
  344. (snd_pcm_format_physical_width(fmt)
  345. / 8));
  346. }
  347. return n;
  348. }
  349. static int
  350. snd_harmony_playback_prepare(snd_pcm_substream_t *ss)
  351. {
  352. harmony_t *h = snd_pcm_substream_chip(ss);
  353. snd_pcm_runtime_t *rt = ss->runtime;
  354. if (h->st.capturing)
  355. return -EBUSY;
  356. h->pbuf.size = snd_pcm_lib_buffer_bytes(ss);
  357. h->pbuf.count = snd_pcm_lib_period_bytes(ss);
  358. h->pbuf.buf = 0;
  359. h->st.playing = 0;
  360. h->st.rate = snd_harmony_rate_bits(rt->rate);
  361. h->st.format = snd_harmony_set_data_format(h, rt->format, 0);
  362. if (rt->channels == 2)
  363. h->st.stereo = HARMONY_SS_STEREO;
  364. else
  365. h->st.stereo = HARMONY_SS_MONO;
  366. harmony_set_control(h);
  367. h->pbuf.addr = rt->dma_addr;
  368. return 0;
  369. }
  370. static int
  371. snd_harmony_capture_prepare(snd_pcm_substream_t *ss)
  372. {
  373. harmony_t *h = snd_pcm_substream_chip(ss);
  374. snd_pcm_runtime_t *rt = ss->runtime;
  375. if (h->st.playing)
  376. return -EBUSY;
  377. h->cbuf.size = snd_pcm_lib_buffer_bytes(ss);
  378. h->cbuf.count = snd_pcm_lib_period_bytes(ss);
  379. h->cbuf.buf = 0;
  380. h->st.capturing = 0;
  381. h->st.rate = snd_harmony_rate_bits(rt->rate);
  382. h->st.format = snd_harmony_set_data_format(h, rt->format, 0);
  383. if (rt->channels == 2)
  384. h->st.stereo = HARMONY_SS_STEREO;
  385. else
  386. h->st.stereo = HARMONY_SS_MONO;
  387. harmony_set_control(h);
  388. h->cbuf.addr = rt->dma_addr;
  389. return 0;
  390. }
  391. static snd_pcm_uframes_t
  392. snd_harmony_playback_pointer(snd_pcm_substream_t *ss)
  393. {
  394. snd_pcm_runtime_t *rt = ss->runtime;
  395. harmony_t *h = snd_pcm_substream_chip(ss);
  396. unsigned long pcuradd;
  397. unsigned long played;
  398. if (!(h->st.playing) || (h->psubs == NULL))
  399. return 0;
  400. if ((h->pbuf.addr == 0) || (h->pbuf.size == 0))
  401. return 0;
  402. pcuradd = harmony_read(h, HARMONY_PCURADD);
  403. played = pcuradd - h->pbuf.addr;
  404. #ifdef HARMONY_DEBUG
  405. printk(KERN_DEBUG PFX "playback_pointer is 0x%lx-0x%lx = %d bytes\n",
  406. pcuradd, h->pbuf.addr, played);
  407. #endif
  408. if (pcuradd > h->pbuf.addr + h->pbuf.size) {
  409. return 0;
  410. }
  411. return bytes_to_frames(rt, played);
  412. }
  413. static snd_pcm_uframes_t
  414. snd_harmony_capture_pointer(snd_pcm_substream_t *ss)
  415. {
  416. snd_pcm_runtime_t *rt = ss->runtime;
  417. harmony_t *h = snd_pcm_substream_chip(ss);
  418. unsigned long rcuradd;
  419. unsigned long caught;
  420. if (!(h->st.capturing) || (h->csubs == NULL))
  421. return 0;
  422. if ((h->cbuf.addr == 0) || (h->cbuf.size == 0))
  423. return 0;
  424. rcuradd = harmony_read(h, HARMONY_RCURADD);
  425. caught = rcuradd - h->cbuf.addr;
  426. #ifdef HARMONY_DEBUG
  427. printk(KERN_DEBUG PFX "capture_pointer is 0x%lx-0x%lx = %d bytes\n",
  428. rcuradd, h->cbuf.addr, caught);
  429. #endif
  430. if (rcuradd > h->cbuf.addr + h->cbuf.size) {
  431. return 0;
  432. }
  433. return bytes_to_frames(rt, caught);
  434. }
  435. static int
  436. snd_harmony_playback_open(snd_pcm_substream_t *ss)
  437. {
  438. harmony_t *h = snd_pcm_substream_chip(ss);
  439. snd_pcm_runtime_t *rt = ss->runtime;
  440. int err;
  441. h->psubs = ss;
  442. rt->hw = snd_harmony_playback;
  443. snd_pcm_hw_constraint_list(rt, 0, SNDRV_PCM_HW_PARAM_RATE,
  444. &hw_constraint_rates);
  445. err = snd_pcm_hw_constraint_integer(rt, SNDRV_PCM_HW_PARAM_PERIODS);
  446. if (err < 0)
  447. return err;
  448. return 0;
  449. }
  450. static int
  451. snd_harmony_capture_open(snd_pcm_substream_t *ss)
  452. {
  453. harmony_t *h = snd_pcm_substream_chip(ss);
  454. snd_pcm_runtime_t *rt = ss->runtime;
  455. int err;
  456. h->csubs = ss;
  457. rt->hw = snd_harmony_capture;
  458. snd_pcm_hw_constraint_list(rt, 0, SNDRV_PCM_HW_PARAM_RATE,
  459. &hw_constraint_rates);
  460. err = snd_pcm_hw_constraint_integer(rt, SNDRV_PCM_HW_PARAM_PERIODS);
  461. if (err < 0)
  462. return err;
  463. return 0;
  464. }
  465. static int
  466. snd_harmony_playback_close(snd_pcm_substream_t *ss)
  467. {
  468. harmony_t *h = snd_pcm_substream_chip(ss);
  469. h->psubs = NULL;
  470. return 0;
  471. }
  472. static int
  473. snd_harmony_capture_close(snd_pcm_substream_t *ss)
  474. {
  475. harmony_t *h = snd_pcm_substream_chip(ss);
  476. h->csubs = NULL;
  477. return 0;
  478. }
  479. static int
  480. snd_harmony_hw_params(snd_pcm_substream_t *ss,
  481. snd_pcm_hw_params_t *hw)
  482. {
  483. int err;
  484. harmony_t *h = snd_pcm_substream_chip(ss);
  485. err = snd_pcm_lib_malloc_pages(ss, params_buffer_bytes(hw));
  486. if (err > 0 && h->dma.type == SNDRV_DMA_TYPE_CONTINUOUS)
  487. ss->runtime->dma_addr = __pa(ss->runtime->dma_area);
  488. return err;
  489. }
  490. static int
  491. snd_harmony_hw_free(snd_pcm_substream_t *ss)
  492. {
  493. return snd_pcm_lib_free_pages(ss);
  494. }
  495. static snd_pcm_ops_t snd_harmony_playback_ops = {
  496. .open = snd_harmony_playback_open,
  497. .close = snd_harmony_playback_close,
  498. .ioctl = snd_pcm_lib_ioctl,
  499. .hw_params = snd_harmony_hw_params,
  500. .hw_free = snd_harmony_hw_free,
  501. .prepare = snd_harmony_playback_prepare,
  502. .trigger = snd_harmony_playback_trigger,
  503. .pointer = snd_harmony_playback_pointer,
  504. };
  505. static snd_pcm_ops_t snd_harmony_capture_ops = {
  506. .open = snd_harmony_capture_open,
  507. .close = snd_harmony_capture_close,
  508. .ioctl = snd_pcm_lib_ioctl,
  509. .hw_params = snd_harmony_hw_params,
  510. .hw_free = snd_harmony_hw_free,
  511. .prepare = snd_harmony_capture_prepare,
  512. .trigger = snd_harmony_capture_trigger,
  513. .pointer = snd_harmony_capture_pointer,
  514. };
  515. static int
  516. snd_harmony_pcm_init(harmony_t *h)
  517. {
  518. snd_pcm_t *pcm;
  519. int err;
  520. harmony_disable_interrupts(h);
  521. err = snd_pcm_new(h->card, "harmony", 0, 1, 1, &pcm);
  522. if (err < 0)
  523. return err;
  524. snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
  525. &snd_harmony_playback_ops);
  526. snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
  527. &snd_harmony_capture_ops);
  528. pcm->private_data = h;
  529. pcm->info_flags = 0;
  530. strcpy(pcm->name, "harmony");
  531. h->pcm = pcm;
  532. h->psubs = NULL;
  533. h->csubs = NULL;
  534. /* initialize graveyard buffer */
  535. h->dma.type = SNDRV_DMA_TYPE_DEV;
  536. h->dma.dev = &h->dev->dev;
  537. err = snd_dma_alloc_pages(h->dma.type,
  538. h->dma.dev,
  539. BUF_SIZE*GRAVEYARD_BUFS,
  540. &h->gdma);
  541. if (err < 0) {
  542. printk(KERN_ERR PFX "cannot allocate graveyard buffer!\n");
  543. return err;
  544. }
  545. /* initialize silence buffers */
  546. err = snd_dma_alloc_pages(h->dma.type,
  547. h->dma.dev,
  548. BUF_SIZE*SILENCE_BUFS,
  549. &h->sdma);
  550. if (err < 0) {
  551. printk(KERN_ERR PFX "cannot allocate silence buffer!\n");
  552. return err;
  553. }
  554. /* pre-allocate space for DMA */
  555. err = snd_pcm_lib_preallocate_pages_for_all(pcm, h->dma.type,
  556. h->dma.dev,
  557. MAX_BUF_SIZE,
  558. MAX_BUF_SIZE);
  559. if (err < 0) {
  560. printk(KERN_ERR PFX "buffer allocation error: %d\n", err);
  561. return err;
  562. }
  563. h->st.format = snd_harmony_set_data_format(h,
  564. SNDRV_PCM_FORMAT_S16_BE, 1);
  565. return 0;
  566. }
  567. static void
  568. snd_harmony_set_new_gain(harmony_t *h)
  569. {
  570. harmony_wait_for_control(h);
  571. harmony_write(h, HARMONY_GAINCTL, h->st.gain);
  572. }
  573. static int
  574. snd_harmony_mixercontrol_info(snd_kcontrol_t *kc,
  575. snd_ctl_elem_info_t *uinfo)
  576. {
  577. int mask = (kc->private_value >> 16) & 0xff;
  578. int left_shift = (kc->private_value) & 0xff;
  579. int right_shift = (kc->private_value >> 8) & 0xff;
  580. uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN :
  581. SNDRV_CTL_ELEM_TYPE_INTEGER;
  582. uinfo->count = left_shift == right_shift ? 1 : 2;
  583. uinfo->value.integer.min = 0;
  584. uinfo->value.integer.max = mask;
  585. return 0;
  586. }
  587. static int
  588. snd_harmony_volume_get(snd_kcontrol_t *kc,
  589. snd_ctl_elem_value_t *ucontrol)
  590. {
  591. harmony_t *h = snd_kcontrol_chip(kc);
  592. int shift_left = (kc->private_value) & 0xff;
  593. int shift_right = (kc->private_value >> 8) & 0xff;
  594. int mask = (kc->private_value >> 16) & 0xff;
  595. int invert = (kc->private_value >> 24) & 0xff;
  596. int left, right;
  597. unsigned long flags;
  598. spin_lock_irqsave(&h->mixer_lock, flags);
  599. left = (h->st.gain >> shift_left) & mask;
  600. right = (h->st.gain >> shift_right) & mask;
  601. if (invert) {
  602. left = mask - left;
  603. right = mask - right;
  604. }
  605. ucontrol->value.integer.value[0] = left;
  606. ucontrol->value.integer.value[1] = right;
  607. spin_unlock_irqrestore(&h->mixer_lock, flags);
  608. return 0;
  609. }
  610. static int
  611. snd_harmony_volume_put(snd_kcontrol_t *kc,
  612. snd_ctl_elem_value_t *ucontrol)
  613. {
  614. harmony_t *h = snd_kcontrol_chip(kc);
  615. int shift_left = (kc->private_value) & 0xff;
  616. int shift_right = (kc->private_value >> 8) & 0xff;
  617. int mask = (kc->private_value >> 16) & 0xff;
  618. int invert = (kc->private_value >> 24) & 0xff;
  619. int left, right;
  620. int old_gain = h->st.gain;
  621. unsigned long flags;
  622. left = ucontrol->value.integer.value[0] & mask;
  623. right = ucontrol->value.integer.value[1] & mask;
  624. if (invert) {
  625. left = mask - left;
  626. right = mask - right;
  627. }
  628. spin_lock_irqsave(&h->mixer_lock, flags);
  629. h->st.gain &= ~( (mask << shift_right) | (mask << shift_left) );
  630. h->st.gain |= ( (left << shift_left) | (right << shift_right) );
  631. snd_harmony_set_new_gain(h);
  632. spin_unlock_irqrestore(&h->mixer_lock, flags);
  633. return (old_gain - h->st.gain);
  634. }
  635. #define HARMONY_CONTROLS (sizeof(snd_harmony_controls)/ \
  636. sizeof(snd_kcontrol_new_t))
  637. #define HARMONY_VOLUME(xname, left_shift, right_shift, mask, invert) \
  638. { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
  639. .info = snd_harmony_mixercontrol_info, \
  640. .get = snd_harmony_volume_get, .put = snd_harmony_volume_put, \
  641. .private_value = ((left_shift) | ((right_shift) << 8) | \
  642. ((mask) << 16) | ((invert) << 24)) }
  643. static snd_kcontrol_new_t snd_harmony_controls[] = {
  644. HARMONY_VOLUME("Playback Volume", HARMONY_GAIN_LO_SHIFT,
  645. HARMONY_GAIN_RO_SHIFT, HARMONY_GAIN_OUT, 1),
  646. HARMONY_VOLUME("Capture Volume", HARMONY_GAIN_LI_SHIFT,
  647. HARMONY_GAIN_RI_SHIFT, HARMONY_GAIN_IN, 0),
  648. };
  649. static void __init
  650. snd_harmony_mixer_reset(harmony_t *h)
  651. {
  652. harmony_mute(h);
  653. harmony_reset(h);
  654. h->st.gain = HARMONY_GAIN_DEFAULT;
  655. harmony_unmute(h);
  656. }
  657. static int __init
  658. snd_harmony_mixer_init(harmony_t *h)
  659. {
  660. snd_card_t *card = h->card;
  661. int idx, err;
  662. snd_assert(h != NULL, return -EINVAL);
  663. strcpy(card->mixername, "Harmony Gain control interface");
  664. for (idx = 0; idx < HARMONY_CONTROLS; idx++) {
  665. err = snd_ctl_add(card,
  666. snd_ctl_new1(&snd_harmony_controls[idx], h));
  667. if (err < 0)
  668. return err;
  669. }
  670. snd_harmony_mixer_reset(h);
  671. return 0;
  672. }
  673. static int
  674. snd_harmony_free(harmony_t *h)
  675. {
  676. if (h->gdma.addr)
  677. snd_dma_free_pages(&h->gdma);
  678. if (h->sdma.addr)
  679. snd_dma_free_pages(&h->sdma);
  680. if (h->irq >= 0)
  681. free_irq(h->irq, h);
  682. if (h->iobase)
  683. iounmap(h->iobase);
  684. parisc_set_drvdata(h->dev, NULL);
  685. kfree(h);
  686. return 0;
  687. }
  688. static int
  689. snd_harmony_dev_free(snd_device_t *dev)
  690. {
  691. harmony_t *h = dev->device_data;
  692. return snd_harmony_free(h);
  693. }
  694. static int __devinit
  695. snd_harmony_create(snd_card_t *card,
  696. struct parisc_device *padev,
  697. harmony_t **rchip)
  698. {
  699. int err;
  700. harmony_t *h;
  701. static snd_device_ops_t ops = {
  702. .dev_free = snd_harmony_dev_free,
  703. };
  704. *rchip = NULL;
  705. h = kmalloc(sizeof(*h), GFP_KERNEL);
  706. if (h == NULL)
  707. return -ENOMEM;
  708. memset(&h->st, 0, sizeof(h->st));
  709. memset(&h->stats, 0, sizeof(h->stats));
  710. memset(&h->pbuf, 0, sizeof(h->pbuf));
  711. memset(&h->cbuf, 0, sizeof(h->cbuf));
  712. h->hpa = padev->hpa;
  713. h->card = card;
  714. h->dev = padev;
  715. h->irq = padev->irq;
  716. h->iobase = ioremap_nocache(padev->hpa, HARMONY_SIZE);
  717. if (h->iobase == NULL) {
  718. printk(KERN_ERR PFX "unable to remap hpa 0x%lx\n",
  719. padev->hpa);
  720. err = -EBUSY;
  721. goto free_and_ret;
  722. }
  723. err = request_irq(h->irq, snd_harmony_interrupt, 0,
  724. "harmony", h);
  725. if (err) {
  726. printk(KERN_ERR PFX "could not obtain interrupt %d",
  727. h->irq);
  728. goto free_and_ret;
  729. }
  730. spin_lock_init(&h->mixer_lock);
  731. spin_lock_init(&h->lock);
  732. if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
  733. h, &ops)) < 0) {
  734. goto free_and_ret;
  735. }
  736. *rchip = h;
  737. return 0;
  738. free_and_ret:
  739. snd_harmony_free(h);
  740. return err;
  741. }
  742. static int __devinit
  743. snd_harmony_probe(struct parisc_device *padev)
  744. {
  745. int err;
  746. static int dev;
  747. snd_card_t *card;
  748. harmony_t *h;
  749. static int index = SNDRV_DEFAULT_IDX1;
  750. static char *id = SNDRV_DEFAULT_STR1;
  751. h = parisc_get_drvdata(padev);
  752. if (h != NULL) {
  753. return -ENODEV;
  754. }
  755. card = snd_card_new(index, id, THIS_MODULE, 0);
  756. if (card == NULL)
  757. return -ENOMEM;
  758. err = snd_harmony_create(card, padev, &h);
  759. if (err < 0) {
  760. goto free_and_ret;
  761. }
  762. err = snd_harmony_pcm_init(h);
  763. if (err < 0) {
  764. goto free_and_ret;
  765. }
  766. err = snd_harmony_mixer_init(h);
  767. if (err < 0) {
  768. goto free_and_ret;
  769. }
  770. strcpy(card->driver, "harmony");
  771. strcpy(card->shortname, "Harmony");
  772. sprintf(card->longname, "%s at 0x%lx, irq %i",
  773. card->shortname, h->hpa, h->irq);
  774. err = snd_card_register(card);
  775. if (err < 0) {
  776. goto free_and_ret;
  777. }
  778. dev++;
  779. parisc_set_drvdata(padev, h);
  780. return 0;
  781. free_and_ret:
  782. snd_card_free(card);
  783. return err;
  784. }
  785. static int __devexit
  786. snd_harmony_remove(struct parisc_device *padev)
  787. {
  788. harmony_t *h = parisc_get_drvdata(padev);
  789. snd_card_free(h->card);
  790. return 0;
  791. }
  792. static struct parisc_driver snd_harmony_driver = {
  793. .name = "harmony",
  794. .id_table = snd_harmony_devtable,
  795. .probe = snd_harmony_probe,
  796. .remove = snd_harmony_remove,
  797. };
  798. static int __init
  799. alsa_harmony_init(void)
  800. {
  801. int err;
  802. err = register_parisc_driver(&snd_harmony_driver);
  803. if (err < 0) {
  804. printk(KERN_ERR PFX "device not found\n");
  805. return err;
  806. }
  807. return 0;
  808. }
  809. static void __exit
  810. alsa_harmony_fini(void)
  811. {
  812. int err;
  813. err = unregister_parisc_driver(&snd_harmony_driver);
  814. if (err < 0) {
  815. printk(KERN_ERR PFX "failed to unregister\n");
  816. }
  817. return;
  818. }
  819. MODULE_LICENSE("GPL");
  820. MODULE_AUTHOR("Kyle McMartin <kyle@parisc-linux.org>");
  821. MODULE_DESCRIPTION("Harmony sound driver");
  822. module_init(alsa_harmony_init);
  823. module_exit(alsa_harmony_fini);