harmony.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966
  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. guard(spinlock_irqsave)(&h->mixer_lock);
  125. harmony_wait_for_control(h);
  126. harmony_write(h, HARMONY_GAINCTL, HARMONY_GAIN_SILENCE);
  127. }
  128. static void
  129. harmony_unmute(struct snd_harmony *h)
  130. {
  131. guard(spinlock_irqsave)(&h->mixer_lock);
  132. harmony_wait_for_control(h);
  133. harmony_write(h, HARMONY_GAINCTL, h->st.gain);
  134. }
  135. static void
  136. harmony_set_control(struct snd_harmony *h)
  137. {
  138. u32 ctrl;
  139. guard(spinlock_irqsave)(&h->lock);
  140. ctrl = (HARMONY_CNTL_C |
  141. (h->st.format << 6) |
  142. (h->st.stereo << 5) |
  143. (h->st.rate));
  144. harmony_wait_for_control(h);
  145. harmony_write(h, HARMONY_CNTL, ctrl);
  146. }
  147. static irqreturn_t
  148. snd_harmony_interrupt(int irq, void *dev)
  149. {
  150. u32 dstatus;
  151. struct snd_harmony *h = dev;
  152. scoped_guard(spinlock, &h->lock) {
  153. harmony_disable_interrupts(h);
  154. harmony_wait_for_control(h);
  155. dstatus = harmony_read(h, HARMONY_DSTATUS);
  156. }
  157. if (dstatus & HARMONY_DSTATUS_PN) {
  158. if (h->psubs && h->st.playing) {
  159. scoped_guard(spinlock, &h->lock) {
  160. h->pbuf.buf += h->pbuf.count; /* PAGE_SIZE */
  161. h->pbuf.buf %= h->pbuf.size; /* MAX_BUFS*PAGE_SIZE */
  162. harmony_write(h, HARMONY_PNXTADD,
  163. h->pbuf.addr + h->pbuf.buf);
  164. h->stats.play_intr++;
  165. }
  166. snd_pcm_period_elapsed(h->psubs);
  167. } else {
  168. scoped_guard(spinlock, &h->lock) {
  169. harmony_write(h, HARMONY_PNXTADD, h->sdma.addr);
  170. h->stats.silence_intr++;
  171. }
  172. }
  173. }
  174. if (dstatus & HARMONY_DSTATUS_RN) {
  175. if (h->csubs && h->st.capturing) {
  176. scoped_guard(spinlock, &h->lock) {
  177. h->cbuf.buf += h->cbuf.count;
  178. h->cbuf.buf %= h->cbuf.size;
  179. harmony_write(h, HARMONY_RNXTADD,
  180. h->cbuf.addr + h->cbuf.buf);
  181. h->stats.rec_intr++;
  182. }
  183. snd_pcm_period_elapsed(h->csubs);
  184. } else {
  185. scoped_guard(spinlock, &h->lock) {
  186. harmony_write(h, HARMONY_RNXTADD, h->gdma.addr);
  187. h->stats.graveyard_intr++;
  188. }
  189. }
  190. }
  191. scoped_guard(spinlock, &h->lock) {
  192. harmony_enable_interrupts(h);
  193. }
  194. return IRQ_HANDLED;
  195. }
  196. static unsigned int
  197. snd_harmony_rate_bits(int rate)
  198. {
  199. unsigned int i;
  200. for (i = 0; i < ARRAY_SIZE(snd_harmony_rates); i++)
  201. if (snd_harmony_rates[i] == rate)
  202. return rate_bits[i];
  203. return HARMONY_SR_44KHZ;
  204. }
  205. static const struct snd_pcm_hardware snd_harmony_playback =
  206. {
  207. .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
  208. SNDRV_PCM_INFO_JOINT_DUPLEX | SNDRV_PCM_INFO_MMAP_VALID |
  209. SNDRV_PCM_INFO_BLOCK_TRANSFER),
  210. .formats = (SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_MU_LAW |
  211. SNDRV_PCM_FMTBIT_A_LAW),
  212. .rates = (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_48000 |
  213. SNDRV_PCM_RATE_KNOT),
  214. .rate_min = 5512,
  215. .rate_max = 48000,
  216. .channels_min = 1,
  217. .channels_max = 2,
  218. .buffer_bytes_max = MAX_BUF_SIZE,
  219. .period_bytes_min = BUF_SIZE,
  220. .period_bytes_max = BUF_SIZE,
  221. .periods_min = 1,
  222. .periods_max = MAX_BUFS,
  223. .fifo_size = 0,
  224. };
  225. static const struct snd_pcm_hardware snd_harmony_capture =
  226. {
  227. .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
  228. SNDRV_PCM_INFO_JOINT_DUPLEX | SNDRV_PCM_INFO_MMAP_VALID |
  229. SNDRV_PCM_INFO_BLOCK_TRANSFER),
  230. .formats = (SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_MU_LAW |
  231. SNDRV_PCM_FMTBIT_A_LAW),
  232. .rates = (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_48000 |
  233. SNDRV_PCM_RATE_KNOT),
  234. .rate_min = 5512,
  235. .rate_max = 48000,
  236. .channels_min = 1,
  237. .channels_max = 2,
  238. .buffer_bytes_max = MAX_BUF_SIZE,
  239. .period_bytes_min = BUF_SIZE,
  240. .period_bytes_max = BUF_SIZE,
  241. .periods_min = 1,
  242. .periods_max = MAX_BUFS,
  243. .fifo_size = 0,
  244. };
  245. static int
  246. snd_harmony_playback_trigger(struct snd_pcm_substream *ss, int cmd)
  247. {
  248. struct snd_harmony *h = snd_pcm_substream_chip(ss);
  249. if (h->st.capturing)
  250. return -EBUSY;
  251. guard(spinlock)(&h->lock);
  252. switch (cmd) {
  253. case SNDRV_PCM_TRIGGER_START:
  254. h->st.playing = 1;
  255. harmony_write(h, HARMONY_PNXTADD, h->pbuf.addr);
  256. harmony_write(h, HARMONY_RNXTADD, h->gdma.addr);
  257. harmony_unmute(h);
  258. harmony_enable_interrupts(h);
  259. break;
  260. case SNDRV_PCM_TRIGGER_STOP:
  261. h->st.playing = 0;
  262. harmony_mute(h);
  263. harmony_write(h, HARMONY_PNXTADD, h->sdma.addr);
  264. harmony_disable_interrupts(h);
  265. break;
  266. case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  267. case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  268. case SNDRV_PCM_TRIGGER_SUSPEND:
  269. default:
  270. snd_BUG();
  271. return -EINVAL;
  272. }
  273. return 0;
  274. }
  275. static int
  276. snd_harmony_capture_trigger(struct snd_pcm_substream *ss, int cmd)
  277. {
  278. struct snd_harmony *h = snd_pcm_substream_chip(ss);
  279. if (h->st.playing)
  280. return -EBUSY;
  281. guard(spinlock)(&h->lock);
  282. switch (cmd) {
  283. case SNDRV_PCM_TRIGGER_START:
  284. h->st.capturing = 1;
  285. harmony_write(h, HARMONY_PNXTADD, h->sdma.addr);
  286. harmony_write(h, HARMONY_RNXTADD, h->cbuf.addr);
  287. harmony_unmute(h);
  288. harmony_enable_interrupts(h);
  289. break;
  290. case SNDRV_PCM_TRIGGER_STOP:
  291. h->st.capturing = 0;
  292. harmony_mute(h);
  293. harmony_write(h, HARMONY_RNXTADD, h->gdma.addr);
  294. harmony_disable_interrupts(h);
  295. break;
  296. case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  297. case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  298. case SNDRV_PCM_TRIGGER_SUSPEND:
  299. default:
  300. snd_BUG();
  301. return -EINVAL;
  302. }
  303. return 0;
  304. }
  305. static int
  306. snd_harmony_set_data_format(struct snd_harmony *h, int fmt, int force)
  307. {
  308. int o = h->st.format;
  309. int n;
  310. switch(fmt) {
  311. case SNDRV_PCM_FORMAT_S16_BE:
  312. n = HARMONY_DF_16BIT_LINEAR;
  313. break;
  314. case SNDRV_PCM_FORMAT_A_LAW:
  315. n = HARMONY_DF_8BIT_ALAW;
  316. break;
  317. case SNDRV_PCM_FORMAT_MU_LAW:
  318. n = HARMONY_DF_8BIT_ULAW;
  319. break;
  320. default:
  321. n = HARMONY_DF_16BIT_LINEAR;
  322. break;
  323. }
  324. if (force || o != n) {
  325. snd_pcm_format_set_silence(fmt, h->sdma.area, SILENCE_BUFSZ /
  326. (snd_pcm_format_physical_width(fmt)
  327. / 8));
  328. }
  329. return n;
  330. }
  331. static int
  332. snd_harmony_playback_prepare(struct snd_pcm_substream *ss)
  333. {
  334. struct snd_harmony *h = snd_pcm_substream_chip(ss);
  335. struct snd_pcm_runtime *rt = ss->runtime;
  336. if (h->st.capturing)
  337. return -EBUSY;
  338. h->pbuf.size = snd_pcm_lib_buffer_bytes(ss);
  339. h->pbuf.count = snd_pcm_lib_period_bytes(ss);
  340. if (h->pbuf.buf >= h->pbuf.size)
  341. h->pbuf.buf = 0;
  342. h->st.playing = 0;
  343. h->st.rate = snd_harmony_rate_bits(rt->rate);
  344. h->st.format = snd_harmony_set_data_format(h, rt->format, 0);
  345. if (rt->channels == 2)
  346. h->st.stereo = HARMONY_SS_STEREO;
  347. else
  348. h->st.stereo = HARMONY_SS_MONO;
  349. harmony_set_control(h);
  350. h->pbuf.addr = rt->dma_addr;
  351. return 0;
  352. }
  353. static int
  354. snd_harmony_capture_prepare(struct snd_pcm_substream *ss)
  355. {
  356. struct snd_harmony *h = snd_pcm_substream_chip(ss);
  357. struct snd_pcm_runtime *rt = ss->runtime;
  358. if (h->st.playing)
  359. return -EBUSY;
  360. h->cbuf.size = snd_pcm_lib_buffer_bytes(ss);
  361. h->cbuf.count = snd_pcm_lib_period_bytes(ss);
  362. if (h->cbuf.buf >= h->cbuf.size)
  363. h->cbuf.buf = 0;
  364. h->st.capturing = 0;
  365. h->st.rate = snd_harmony_rate_bits(rt->rate);
  366. h->st.format = snd_harmony_set_data_format(h, rt->format, 0);
  367. if (rt->channels == 2)
  368. h->st.stereo = HARMONY_SS_STEREO;
  369. else
  370. h->st.stereo = HARMONY_SS_MONO;
  371. harmony_set_control(h);
  372. h->cbuf.addr = rt->dma_addr;
  373. return 0;
  374. }
  375. static snd_pcm_uframes_t
  376. snd_harmony_playback_pointer(struct snd_pcm_substream *ss)
  377. {
  378. struct snd_pcm_runtime *rt = ss->runtime;
  379. struct snd_harmony *h = snd_pcm_substream_chip(ss);
  380. unsigned long pcuradd;
  381. unsigned long played;
  382. if (!(h->st.playing) || (h->psubs == NULL))
  383. return 0;
  384. if ((h->pbuf.addr == 0) || (h->pbuf.size == 0))
  385. return 0;
  386. pcuradd = harmony_read(h, HARMONY_PCURADD);
  387. played = pcuradd - h->pbuf.addr;
  388. #ifdef HARMONY_DEBUG
  389. printk(KERN_DEBUG PFX "playback_pointer is 0x%lx-0x%lx = %d bytes\n",
  390. pcuradd, h->pbuf.addr, played);
  391. #endif
  392. if (pcuradd > h->pbuf.addr + h->pbuf.size) {
  393. return 0;
  394. }
  395. return bytes_to_frames(rt, played);
  396. }
  397. static snd_pcm_uframes_t
  398. snd_harmony_capture_pointer(struct snd_pcm_substream *ss)
  399. {
  400. struct snd_pcm_runtime *rt = ss->runtime;
  401. struct snd_harmony *h = snd_pcm_substream_chip(ss);
  402. unsigned long rcuradd;
  403. unsigned long caught;
  404. if (!(h->st.capturing) || (h->csubs == NULL))
  405. return 0;
  406. if ((h->cbuf.addr == 0) || (h->cbuf.size == 0))
  407. return 0;
  408. rcuradd = harmony_read(h, HARMONY_RCURADD);
  409. caught = rcuradd - h->cbuf.addr;
  410. #ifdef HARMONY_DEBUG
  411. printk(KERN_DEBUG PFX "capture_pointer is 0x%lx-0x%lx = %d bytes\n",
  412. rcuradd, h->cbuf.addr, caught);
  413. #endif
  414. if (rcuradd > h->cbuf.addr + h->cbuf.size) {
  415. return 0;
  416. }
  417. return bytes_to_frames(rt, caught);
  418. }
  419. static int
  420. snd_harmony_playback_open(struct snd_pcm_substream *ss)
  421. {
  422. struct snd_harmony *h = snd_pcm_substream_chip(ss);
  423. struct snd_pcm_runtime *rt = ss->runtime;
  424. int err;
  425. h->psubs = ss;
  426. rt->hw = snd_harmony_playback;
  427. snd_pcm_hw_constraint_list(rt, 0, SNDRV_PCM_HW_PARAM_RATE,
  428. &hw_constraint_rates);
  429. err = snd_pcm_hw_constraint_integer(rt, SNDRV_PCM_HW_PARAM_PERIODS);
  430. if (err < 0)
  431. return err;
  432. return 0;
  433. }
  434. static int
  435. snd_harmony_capture_open(struct snd_pcm_substream *ss)
  436. {
  437. struct snd_harmony *h = snd_pcm_substream_chip(ss);
  438. struct snd_pcm_runtime *rt = ss->runtime;
  439. int err;
  440. h->csubs = ss;
  441. rt->hw = snd_harmony_capture;
  442. snd_pcm_hw_constraint_list(rt, 0, SNDRV_PCM_HW_PARAM_RATE,
  443. &hw_constraint_rates);
  444. err = snd_pcm_hw_constraint_integer(rt, SNDRV_PCM_HW_PARAM_PERIODS);
  445. if (err < 0)
  446. return err;
  447. return 0;
  448. }
  449. static int
  450. snd_harmony_playback_close(struct snd_pcm_substream *ss)
  451. {
  452. struct snd_harmony *h = snd_pcm_substream_chip(ss);
  453. h->psubs = NULL;
  454. return 0;
  455. }
  456. static int
  457. snd_harmony_capture_close(struct snd_pcm_substream *ss)
  458. {
  459. struct snd_harmony *h = snd_pcm_substream_chip(ss);
  460. h->csubs = NULL;
  461. return 0;
  462. }
  463. static const struct snd_pcm_ops snd_harmony_playback_ops = {
  464. .open = snd_harmony_playback_open,
  465. .close = snd_harmony_playback_close,
  466. .prepare = snd_harmony_playback_prepare,
  467. .trigger = snd_harmony_playback_trigger,
  468. .pointer = snd_harmony_playback_pointer,
  469. };
  470. static const struct snd_pcm_ops snd_harmony_capture_ops = {
  471. .open = snd_harmony_capture_open,
  472. .close = snd_harmony_capture_close,
  473. .prepare = snd_harmony_capture_prepare,
  474. .trigger = snd_harmony_capture_trigger,
  475. .pointer = snd_harmony_capture_pointer,
  476. };
  477. static int
  478. snd_harmony_pcm_init(struct snd_harmony *h)
  479. {
  480. struct snd_pcm *pcm;
  481. int err;
  482. if (snd_BUG_ON(!h))
  483. return -EINVAL;
  484. harmony_disable_interrupts(h);
  485. err = snd_pcm_new(h->card, "harmony", 0, 1, 1, &pcm);
  486. if (err < 0)
  487. return err;
  488. snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
  489. &snd_harmony_playback_ops);
  490. snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
  491. &snd_harmony_capture_ops);
  492. pcm->private_data = h;
  493. pcm->info_flags = 0;
  494. strscpy(pcm->name, "harmony");
  495. h->pcm = pcm;
  496. h->psubs = NULL;
  497. h->csubs = NULL;
  498. /* initialize graveyard buffer */
  499. h->dma.type = SNDRV_DMA_TYPE_DEV;
  500. h->dma.dev = &h->dev->dev;
  501. err = snd_dma_alloc_pages(h->dma.type,
  502. h->dma.dev,
  503. BUF_SIZE*GRAVEYARD_BUFS,
  504. &h->gdma);
  505. if (err < 0) {
  506. printk(KERN_ERR PFX "cannot allocate graveyard buffer!\n");
  507. return err;
  508. }
  509. /* initialize silence buffers */
  510. err = snd_dma_alloc_pages(h->dma.type,
  511. h->dma.dev,
  512. BUF_SIZE*SILENCE_BUFS,
  513. &h->sdma);
  514. if (err < 0) {
  515. printk(KERN_ERR PFX "cannot allocate silence buffer!\n");
  516. return err;
  517. }
  518. /* pre-allocate space for DMA */
  519. snd_pcm_set_managed_buffer_all(pcm, h->dma.type, h->dma.dev,
  520. MAX_BUF_SIZE, MAX_BUF_SIZE);
  521. h->st.format = snd_harmony_set_data_format(h,
  522. SNDRV_PCM_FORMAT_S16_BE, 1);
  523. return 0;
  524. }
  525. static void
  526. snd_harmony_set_new_gain(struct snd_harmony *h)
  527. {
  528. harmony_wait_for_control(h);
  529. harmony_write(h, HARMONY_GAINCTL, h->st.gain);
  530. }
  531. static int
  532. snd_harmony_mixercontrol_info(struct snd_kcontrol *kc,
  533. struct snd_ctl_elem_info *uinfo)
  534. {
  535. int mask = (kc->private_value >> 16) & 0xff;
  536. int left_shift = (kc->private_value) & 0xff;
  537. int right_shift = (kc->private_value >> 8) & 0xff;
  538. uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN :
  539. SNDRV_CTL_ELEM_TYPE_INTEGER;
  540. uinfo->count = left_shift == right_shift ? 1 : 2;
  541. uinfo->value.integer.min = 0;
  542. uinfo->value.integer.max = mask;
  543. return 0;
  544. }
  545. static int
  546. snd_harmony_volume_get(struct snd_kcontrol *kc,
  547. struct snd_ctl_elem_value *ucontrol)
  548. {
  549. struct snd_harmony *h = snd_kcontrol_chip(kc);
  550. int shift_left = (kc->private_value) & 0xff;
  551. int shift_right = (kc->private_value >> 8) & 0xff;
  552. int mask = (kc->private_value >> 16) & 0xff;
  553. int invert = (kc->private_value >> 24) & 0xff;
  554. int left, right;
  555. guard(spinlock_irq)(&h->mixer_lock);
  556. left = (h->st.gain >> shift_left) & mask;
  557. right = (h->st.gain >> shift_right) & mask;
  558. if (invert) {
  559. left = mask - left;
  560. right = mask - right;
  561. }
  562. ucontrol->value.integer.value[0] = left;
  563. if (shift_left != shift_right)
  564. ucontrol->value.integer.value[1] = right;
  565. return 0;
  566. }
  567. static int
  568. snd_harmony_volume_put(struct snd_kcontrol *kc,
  569. struct snd_ctl_elem_value *ucontrol)
  570. {
  571. struct snd_harmony *h = snd_kcontrol_chip(kc);
  572. int shift_left = (kc->private_value) & 0xff;
  573. int shift_right = (kc->private_value >> 8) & 0xff;
  574. int mask = (kc->private_value >> 16) & 0xff;
  575. int invert = (kc->private_value >> 24) & 0xff;
  576. int left, right;
  577. int old_gain = h->st.gain;
  578. guard(spinlock_irq)(&h->mixer_lock);
  579. left = ucontrol->value.integer.value[0] & mask;
  580. if (invert)
  581. left = mask - left;
  582. h->st.gain &= ~( (mask << shift_left ) );
  583. h->st.gain |= (left << shift_left);
  584. if (shift_left != shift_right) {
  585. right = ucontrol->value.integer.value[1] & mask;
  586. if (invert)
  587. right = mask - right;
  588. h->st.gain &= ~( (mask << shift_right) );
  589. h->st.gain |= (right << shift_right);
  590. }
  591. snd_harmony_set_new_gain(h);
  592. return h->st.gain != old_gain;
  593. }
  594. static int
  595. snd_harmony_captureroute_info(struct snd_kcontrol *kc,
  596. struct snd_ctl_elem_info *uinfo)
  597. {
  598. static const char * const texts[2] = { "Line", "Mic" };
  599. return snd_ctl_enum_info(uinfo, 1, 2, texts);
  600. }
  601. static int
  602. snd_harmony_captureroute_get(struct snd_kcontrol *kc,
  603. struct snd_ctl_elem_value *ucontrol)
  604. {
  605. struct snd_harmony *h = snd_kcontrol_chip(kc);
  606. int value;
  607. guard(spinlock_irq)(&h->mixer_lock);
  608. value = (h->st.gain >> HARMONY_GAIN_IS_SHIFT) & 1;
  609. ucontrol->value.enumerated.item[0] = value;
  610. return 0;
  611. }
  612. static int
  613. snd_harmony_captureroute_put(struct snd_kcontrol *kc,
  614. struct snd_ctl_elem_value *ucontrol)
  615. {
  616. struct snd_harmony *h = snd_kcontrol_chip(kc);
  617. int value;
  618. int old_gain = h->st.gain;
  619. guard(spinlock_irq)(&h->mixer_lock);
  620. value = ucontrol->value.enumerated.item[0] & 1;
  621. h->st.gain &= ~HARMONY_GAIN_IS_MASK;
  622. h->st.gain |= value << HARMONY_GAIN_IS_SHIFT;
  623. snd_harmony_set_new_gain(h);
  624. return h->st.gain != old_gain;
  625. }
  626. #define HARMONY_CONTROLS ARRAY_SIZE(snd_harmony_controls)
  627. #define HARMONY_VOLUME(xname, left_shift, right_shift, mask, invert) \
  628. { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
  629. .info = snd_harmony_mixercontrol_info, \
  630. .get = snd_harmony_volume_get, .put = snd_harmony_volume_put, \
  631. .private_value = ((left_shift) | ((right_shift) << 8) | \
  632. ((mask) << 16) | ((invert) << 24)) }
  633. static const struct snd_kcontrol_new snd_harmony_controls[] = {
  634. HARMONY_VOLUME("Master Playback Volume", HARMONY_GAIN_LO_SHIFT,
  635. HARMONY_GAIN_RO_SHIFT, HARMONY_GAIN_OUT, 1),
  636. HARMONY_VOLUME("Capture Volume", HARMONY_GAIN_LI_SHIFT,
  637. HARMONY_GAIN_RI_SHIFT, HARMONY_GAIN_IN, 0),
  638. HARMONY_VOLUME("Monitor Volume", HARMONY_GAIN_MA_SHIFT,
  639. HARMONY_GAIN_MA_SHIFT, HARMONY_GAIN_MA, 1),
  640. {
  641. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  642. .name = "Input Route",
  643. .info = snd_harmony_captureroute_info,
  644. .get = snd_harmony_captureroute_get,
  645. .put = snd_harmony_captureroute_put
  646. },
  647. HARMONY_VOLUME("Internal Speaker Switch", HARMONY_GAIN_SE_SHIFT,
  648. HARMONY_GAIN_SE_SHIFT, 1, 0),
  649. HARMONY_VOLUME("Line-Out Switch", HARMONY_GAIN_LE_SHIFT,
  650. HARMONY_GAIN_LE_SHIFT, 1, 0),
  651. HARMONY_VOLUME("Headphones Switch", HARMONY_GAIN_HE_SHIFT,
  652. HARMONY_GAIN_HE_SHIFT, 1, 0),
  653. };
  654. static void
  655. snd_harmony_mixer_reset(struct snd_harmony *h)
  656. {
  657. harmony_mute(h);
  658. harmony_reset(h);
  659. h->st.gain = HARMONY_GAIN_DEFAULT;
  660. harmony_unmute(h);
  661. }
  662. static int
  663. snd_harmony_mixer_init(struct snd_harmony *h)
  664. {
  665. struct snd_card *card;
  666. int idx, err;
  667. if (snd_BUG_ON(!h))
  668. return -EINVAL;
  669. card = h->card;
  670. strscpy(card->mixername, "Harmony Gain control interface");
  671. for (idx = 0; idx < HARMONY_CONTROLS; idx++) {
  672. err = snd_ctl_add(card,
  673. snd_ctl_new1(&snd_harmony_controls[idx], h));
  674. if (err < 0)
  675. return err;
  676. }
  677. snd_harmony_mixer_reset(h);
  678. return 0;
  679. }
  680. static int
  681. snd_harmony_free(struct snd_harmony *h)
  682. {
  683. if (h->gdma.addr)
  684. snd_dma_free_pages(&h->gdma);
  685. if (h->sdma.addr)
  686. snd_dma_free_pages(&h->sdma);
  687. if (h->irq >= 0)
  688. free_irq(h->irq, h);
  689. iounmap(h->iobase);
  690. kfree(h);
  691. return 0;
  692. }
  693. static int
  694. snd_harmony_dev_free(struct snd_device *dev)
  695. {
  696. struct snd_harmony *h = dev->device_data;
  697. return snd_harmony_free(h);
  698. }
  699. static int
  700. snd_harmony_create(struct snd_card *card,
  701. struct parisc_device *padev,
  702. struct snd_harmony **rchip)
  703. {
  704. int err;
  705. struct snd_harmony *h;
  706. static const struct snd_device_ops ops = {
  707. .dev_free = snd_harmony_dev_free,
  708. };
  709. *rchip = NULL;
  710. h = kzalloc_obj(*h);
  711. if (h == NULL)
  712. return -ENOMEM;
  713. h->hpa = padev->hpa.start;
  714. h->card = card;
  715. h->dev = padev;
  716. h->irq = -1;
  717. h->iobase = ioremap(padev->hpa.start, HARMONY_SIZE);
  718. if (h->iobase == NULL) {
  719. printk(KERN_ERR PFX "unable to remap hpa 0x%lx\n",
  720. (unsigned long)padev->hpa.start);
  721. err = -EBUSY;
  722. goto free_and_ret;
  723. }
  724. err = request_irq(padev->irq, snd_harmony_interrupt, 0,
  725. "harmony", h);
  726. if (err) {
  727. printk(KERN_ERR PFX "could not obtain interrupt %d",
  728. padev->irq);
  729. goto free_and_ret;
  730. }
  731. h->irq = padev->irq;
  732. spin_lock_init(&h->mixer_lock);
  733. spin_lock_init(&h->lock);
  734. err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, h, &ops);
  735. if (err < 0)
  736. goto free_and_ret;
  737. *rchip = h;
  738. return 0;
  739. free_and_ret:
  740. snd_harmony_free(h);
  741. return err;
  742. }
  743. static int __init
  744. snd_harmony_probe(struct parisc_device *padev)
  745. {
  746. int err;
  747. struct snd_card *card;
  748. struct snd_harmony *h;
  749. err = snd_card_new(&padev->dev, index, id, THIS_MODULE, 0, &card);
  750. if (err < 0)
  751. return err;
  752. err = snd_harmony_create(card, padev, &h);
  753. if (err < 0)
  754. goto free_and_ret;
  755. err = snd_harmony_pcm_init(h);
  756. if (err < 0)
  757. goto free_and_ret;
  758. err = snd_harmony_mixer_init(h);
  759. if (err < 0)
  760. goto free_and_ret;
  761. strscpy(card->driver, "harmony");
  762. strscpy(card->shortname, "Harmony");
  763. sprintf(card->longname, "%s at 0x%lx, irq %i",
  764. card->shortname, h->hpa, h->irq);
  765. err = snd_card_register(card);
  766. if (err < 0)
  767. goto free_and_ret;
  768. parisc_set_drvdata(padev, card);
  769. return 0;
  770. free_and_ret:
  771. snd_card_free(card);
  772. return err;
  773. }
  774. static void __exit
  775. snd_harmony_remove(struct parisc_device *padev)
  776. {
  777. snd_card_free(parisc_get_drvdata(padev));
  778. }
  779. static struct parisc_driver snd_harmony_driver __refdata = {
  780. .name = "harmony",
  781. .id_table = snd_harmony_devtable,
  782. .probe = snd_harmony_probe,
  783. .remove = __exit_p(snd_harmony_remove),
  784. };
  785. static int __init
  786. alsa_harmony_init(void)
  787. {
  788. return register_parisc_driver(&snd_harmony_driver);
  789. }
  790. static void __exit
  791. alsa_harmony_fini(void)
  792. {
  793. unregister_parisc_driver(&snd_harmony_driver);
  794. }
  795. MODULE_LICENSE("GPL");
  796. MODULE_AUTHOR("Kyle McMartin <kyle@parisc-linux.org>");
  797. MODULE_DESCRIPTION("Harmony sound driver");
  798. module_init(alsa_harmony_init);
  799. module_exit(alsa_harmony_fini);