harmony.c 24 KB

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