s3c6400_i2s.c 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033
  1. /*
  2. * s3c64xx-wm8753.c -- Samsung audio driver for WM8753
  3. * "$Id: s3c6400_i2s.c,v 1.6 2008/01/31 07:22:14 eyryu Exp $"
  4. *
  5. * Copyright 2003 Wolfson Microelectronics PLC.
  6. * Copyright (C) 2007, Ryu Euiyoul <ryu.real@gmail.com>
  7. * Author: Liam Girdwood
  8. * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
  9. * This program is free software; you can redistribute it and/or modify it
  10. * under the terms of the GNU General Public License as published by the
  11. * Free Software Foundation; either version 2 of the License, or (at your
  12. * option) any later version.
  13. *
  14. * Notes:
  15. * The WM8753 is a low power, high quality stereo codec with integrated PCM
  16. * codec designed for portable digital telephony applications.
  17. *
  18. * Features:
  19. * - supports 16 bit mono voice DAC and left ADC in PCM mode
  20. * - support VDAC sample rates of 8k, 12k, 16k, 24k, 48k.
  21. * - support 16 bit stereo playback on HiFi DAC.
  22. * - support HiFi DAC sample rates of 8k, 12k, 16k, 48k.
  23. * - low power consumption
  24. * - support 8753 stand alone and 8753/9712 combi boards
  25. * - workaround for bug#1190412 on Bulverde B0
  26. *
  27. * TODO:
  28. * - Test PM, IOCTL's, recording
  29. * - TEST, TEST and more TESTING and then fix the bugs !
  30. *
  31. * Bugs:
  32. * - SSP2 RX is held high and not working
  33. *
  34. * Revision history
  35. * 26th Aug 2003 Initial version.
  36. * 1st Dec 2003 Version 0.5. Added new sample rates and cleaned up.
  37. * 21st Jan 2004 Audio distortion workaround added, power settings
  38. * have been refined to minimize consumption.
  39. * 2nd Feb 2004 HiFi DAC added.
  40. * 9th Dec 2004 Ported to 2.6.
  41. * 10th Jan 2005 Modified for s3c2442
  42. * 28th Mar 2007 Support at smdk6400 by ryu
  43. */
  44. #include <linux/init.h>
  45. #include <linux/module.h>
  46. #include <linux/kernel.h>
  47. #include <linux/slab.h>
  48. #include <linux/completion.h>
  49. #include <linux/delay.h>
  50. #include <linux/poll.h>
  51. #include <linux/sound.h>
  52. #include <linux/soundcard.h>
  53. #include <linux/errno.h>
  54. #include <linux/device.h>
  55. #include <linux/i2c.h>
  56. #include <linux/i2c-id.h>
  57. #include <linux/pm.h>
  58. #include <linux/platform_device.h>
  59. #include <asm/hardware.h>
  60. #include <asm/irq.h>
  61. #include <asm/uaccess.h>
  62. #include <asm/semaphore.h>
  63. #include <asm/io.h>
  64. #include <asm/dma.h>
  65. #include <asm/arch/regs-iis.h>
  66. #include <asm/arch/regs-s3c6400-clock.h>
  67. #include <asm/arch/regs-gpio.h>
  68. #include "wm8753.h"
  69. #include "s3c6400_pcm.h"
  70. #define AUDIO_NAME "s3c64xx-wm8753"
  71. /*
  72. * HiFi DAC.
  73. *
  74. * Set hifi to 1 to enable the HiFi DAC over the I2S link.
  75. */
  76. static int hifi = 1;
  77. module_param(hifi, int, 0);
  78. MODULE_PARM_DESC(hifi, "Enable the HiFi DAC.");
  79. /*
  80. * Voice ADC/DAC
  81. *
  82. * Set voice to 1 to enable the voice ADC/DAC over the SSP link.
  83. */
  84. static int voice = 1;
  85. module_param(voice, int, 0);
  86. MODULE_PARM_DESC(voice, "Enable the Voice ADC/DAC.");
  87. /* OSS interface to WM8753 */
  88. #define WM8753_STEREO_MASK (SOUND_MASK_VOLUME | SOUND_MASK_PCM | SOUND_MASK_IGAIN)
  89. #define WM8753_SUPPORTED_MASK (WM8753_STEREO_MASK | \
  90. SOUND_MASK_BASS | SOUND_MASK_TREBLE | SOUND_MASK_MIC)
  91. #define WM8753_RECORD_MASK (SOUND_MASK_MIC | SOUND_MASK_IGAIN)
  92. /* taken from ac97_codec.h */
  93. /* original check is not good enough in case FOO is greater than
  94. * SOUND_MIXER_NRDEVICES because the supported_mixers has exactly
  95. * SOUND_MIXER_NRDEVICES elements.
  96. * before matching the given mixer against the bitmask in supported_mixers we
  97. * check if mixer number exceeds maximum allowed size which is as mentioned
  98. * above SOUND_MIXER_NRDEVICES */
  99. #define supported_mixer(CODEC,FOO) ((FOO >= 0) && \
  100. (FOO < SOUND_MIXER_NRDEVICES) && \
  101. (CODEC)->supported_mixers & (1 << FOO))
  102. /* PLL divisors */
  103. #define PLL_N 0x7
  104. #define PLL_K 0x23F548
  105. //#define DBG printk
  106. #define DBG(...)
  107. //static struct clk *iis_clock;
  108. extern struct clk *clk_get(struct device *dev, const char *id);
  109. extern int clk_enable(struct clk *clk);
  110. extern void clk_disable(struct clk *clk);
  111. extern unsigned long clk_get_rate(struct clk *clk);
  112. extern int s3c_audio_attach(struct inode *inode, struct file *file,
  113. audio_state_t * state);
  114. /* default ADC, HiFi and Voice DAC sample rates */
  115. #define WM8753_DEFAULT_HSRATE WM8753_A8D8
  116. #define WM8753_DEFAULT_VSRATE WM8753_VD48K
  117. /*
  118. * WM8753 2 wire address is determined by GPIO5
  119. * state during powerup.
  120. * low = WM8753_2W_ADDR1
  121. * high = WM8753_2W_ADDR2
  122. */
  123. #define WM8753_2W_ADDR1 0x1a
  124. #define WM8753_2W_ADDR2 0x1b
  125. static unsigned short normal_i2c[] = {
  126. WM8753_2W_ADDR1, I2C_CLIENT_END
  127. };
  128. /* Magic definition of all other i2c variables and things */
  129. I2C_CLIENT_INSMOD;
  130. struct codec_t {
  131. char *name;
  132. int modcnt;
  133. int supported_mixers;
  134. int stereo_mixers;
  135. int record_sources;
  136. int codec_rate;
  137. unsigned int mixer_state[SOUND_MIXER_NRDEVICES];
  138. #ifdef CONFIG_PM
  139. struct pm_dev *pm;
  140. #endif /* */
  141. struct i2c_client wm_client;
  142. struct completion i2c_init;
  143. int wm8753_valid;
  144. };
  145. static struct codec_t codec = {
  146. .name = AUDIO_NAME,
  147. .modcnt = 0,
  148. .codec_rate = WM8753_DEFAULT_HSRATE,
  149. .supported_mixers = WM8753_SUPPORTED_MASK,
  150. .stereo_mixers = WM8753_STEREO_MASK,
  151. .record_sources = WM8753_RECORD_MASK,
  152. .wm8753_valid = 0,
  153. };
  154. /*
  155. * wm8753 register cache
  156. * We can't read the WM8753 register space when we
  157. * are using 2 wire for device control, so we cache them instead.
  158. */
  159. static u16 reg_cache[64] = {
  160. 0x0008, 0x0000, 0x000a, 0x000a, 0x0003, 0x0000, 0x0007, 0x01ff,
  161. 0x01ff, 0x000f, 0x000f, 0x007b, 0x0000, 0x0032,
  162. 0x0000, 0x00c3, 0x00c3, 0x00c0, 0x0000, 0x0000,
  163. 0x0000, 0x0000, 0x0000, 0x0000, 0x0040, 0x0010,
  164. 0x018f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0055,
  165. 0x0005, 0x0050, 0x0055, 0x0050, 0x0055, 0x0050,
  166. 0x0055, 0x0179, 0x0179, 0x0179, 0x0179, 0x0079,
  167. 0x0064, 0x0000, 0x0000, 0x0000, 0x0097, 0x0097,
  168. 0x0000, 0x0004, 0x0000, 0x0083, 0x0024, 0x01ba,
  169. 0x0000, 0x0083, 0x0024, 0x01ba
  170. };
  171. static int wm8753_reset(struct i2c_client *client);
  172. static int wm8753_2w_write(struct i2c_client *client, u8 reg, u16 value);
  173. /*
  174. * read wm8753 register cache
  175. */
  176. static inline u16 wm8753_read_cache(u8 reg)
  177. {
  178. return reg_cache[reg - 1];
  179. }
  180. /*
  181. * write wm8753 register cache
  182. */
  183. static inline void wm8753_write_cache(u8 reg, u16 value)
  184. {
  185. reg_cache[reg - 1] = value;
  186. }
  187. /*
  188. * write to the WM8753 register space
  189. */
  190. static int wm8753_2w_write(struct i2c_client *client, u8 reg, u16 value)
  191. {
  192. u8 data[2];
  193. /* data is
  194. * D15..D9 WM8753 register offset
  195. * D8...D0 register data
  196. */
  197. data[0] = (reg << 1) | ((value >> 8) & 0x0001);
  198. data[1] = value & 0x00ff;
  199. if (i2c_master_send(client, data, 2) == 2) {
  200. wm8753_write_cache(reg, value);
  201. return 0;
  202. } else {
  203. printk(KERN_ERR
  204. "%s error: failed to write 0x%x to register 0x%x\n",
  205. AUDIO_NAME, value, reg);
  206. return -EIO;
  207. }
  208. }
  209. static long audio_set_dsp_speed(long val)
  210. {
  211. u32 iispsr = 0, prescaler = 0;
  212. u32 iiscon = 0, iismod = 0, iisfic = 0;
  213. iiscon = S3C_IIS0CON_TXDMACTIVE | S3C_IIS0CON_RXDMACTIVE;
  214. writel(iiscon, S3C_IIS0CON);
  215. /* Setup the EPLL clock source */
  216. writel(0, S3C_EPLL_CON1);
  217. switch (val) {
  218. case 8000:
  219. case 16000:
  220. case 32000:
  221. writel((1 << 31) | (128 << 16) | (25 << 8) | (0 << 0),
  222. S3C_EPLL_CON0);
  223. break;
  224. case 48000:
  225. writel((1 << 31) | (192 << 16) | (25 << 8) | (0 << 0),
  226. S3C_EPLL_CON0);
  227. break;
  228. case 11025:
  229. case 22050:
  230. case 44100:
  231. default:
  232. writel((1 << 31) | (254 << 16) | (9 << 8) | (2 << 0),
  233. S3C_EPLL_CON0);
  234. break;
  235. }
  236. while (!(readl(S3C_EPLL_CON0) & (1 << 30)));
  237. //MUXepll : FOUTepll
  238. writel(readl(S3C_CLK_SRC) | S3C_CLKSRC_EPLL_CLKSEL, S3C_CLK_SRC);
  239. //AUDIO0 sel : FOUTepll
  240. writel((readl(S3C_CLK_SRC) & ~(0x7 << 7)) | (0 << 7), S3C_CLK_SRC);
  241. //CLK_DIV2 setting
  242. writel(0x0, S3C_CLK_DIV2);
  243. /* FIFO is flushed before operation */
  244. iisfic = S3C_IIS_TX_FLUSH | S3C_IIS_RX_FLUSH;
  245. writel(iisfic, S3C_IIS0FIC);
  246. writel(0, S3C_IIS0FIC);
  247. /* Clear I2S prescaler value [13:8] and disable prescaler */
  248. iispsr = readl(S3C_IIS0PSR);
  249. iispsr &= ~((0x3f << 8) | (1 << 15));
  250. writel(iispsr, S3C_IIS0PSR);
  251. /* Configure I2SMOD */
  252. iismod =
  253. S3C_IIS0MOD_IMS_EXTERNAL_MASTER | S3C_IIS0MOD_TXRXMODE
  254. | S3C_IIS0MOD_IIS | S3C_IIS0MOD_32FS | S3C_IIS0MOD_16BIT;
  255. iismod |= S3C_IIS0MOD_384FS;
  256. writel(iismod, S3C_IIS0MOD);
  257. switch (val) {
  258. case 8000:
  259. case 11025:
  260. prescaler = 19;
  261. break;
  262. case 16000:
  263. case 22050:
  264. prescaler = 9;
  265. break;
  266. case 32000:
  267. case 44100:
  268. case 48000:
  269. default:
  270. prescaler = 4;
  271. break;
  272. }
  273. writel(readl(S3C_IIS0PSR) | (prescaler << 8) | (1 << 15),
  274. S3C_IIS0PSR);
  275. DBG("#### IISCON: 0x%08x IISMOD: 0x%08x IISPSR: 0x%08x\n",
  276. readl(S3C_IIS0CON), readl(S3C_IIS0MOD), readl(S3C_IIS0PSR));
  277. iiscon |= S3C_IIS0CON_I2SACTIVE;
  278. writel(iiscon, S3C_IIS0CON);
  279. return val;
  280. }
  281. static int wm8753_get_mixer(int cmd)
  282. {
  283. int val = 0;
  284. u16 r = 0, l = 0;
  285. switch (cmd) {
  286. case SOUND_MIXER_VOLUME: /* OUT1 Volume */
  287. l = wm8753_read_cache(WM8753_LOUT1V) & 0x7f;
  288. r = wm8753_read_cache(WM8753_ROUT1V) & 0x7f;
  289. break;
  290. case SOUND_MIXER_BASS: /* bass */
  291. l = wm8753_read_cache(WM8753_BASS) & 0x0f;
  292. break;
  293. case SOUND_MIXER_TREBLE: /* treble */
  294. l = wm8753_read_cache(WM8753_TREBLE) & 0x0f;
  295. break;
  296. case SOUND_MIXER_SYNTH:
  297. break;
  298. case SOUND_MIXER_PCM:
  299. break;
  300. case SOUND_MIXER_SPEAKER: /* OUT2 Volume */
  301. l = wm8753_read_cache(WM8753_LOUT2V) & 0x7f;
  302. r = wm8753_read_cache(WM8753_ROUT2V) & 0x7f;
  303. break;
  304. case SOUND_MIXER_LINE:
  305. break;
  306. case SOUND_MIXER_MIC:
  307. l = wm8753_read_cache(WM8753_INCTL1) & 0x060;
  308. r = wm8753_read_cache(WM8753_INCTL1) & 0x180;
  309. break;
  310. case SOUND_MIXER_CD:
  311. break;
  312. case SOUND_MIXER_IMIX: /* Recording monitor */
  313. break;
  314. case SOUND_MIXER_ALTPCM:
  315. break;
  316. case SOUND_MIXER_RECLEV: /* Recording level */
  317. break;
  318. case SOUND_MIXER_IGAIN: /* Input gain */
  319. l = wm8753_read_cache(WM8753_LADC) & 0xff;
  320. r = wm8753_read_cache(WM8753_RADC) & 0xff;
  321. break;
  322. case SOUND_MIXER_OGAIN: /* Output gain */
  323. l = wm8753_read_cache(WM8753_LDAC) & 0xff;
  324. r = wm8753_read_cache(WM8753_RDAC) & 0xff;
  325. break;
  326. default:
  327. DBG(KERN_WARNING "unknown mixer IOCTL\n");
  328. return -EINVAL;
  329. }
  330. /* mix left and right */
  331. val = ((l << 8) & 0xff00) + (r & 0xff);
  332. return val;
  333. }
  334. /* ** NOT TESTED ** */
  335. static int wm8753_set_mixer(int cmd, int val)
  336. {
  337. int ret = 0;
  338. u16 reg;
  339. unsigned int left, right;
  340. /* separate left and right settings */
  341. right = ((val >> 8) & 0xff);
  342. right = right + 0x32;
  343. left = (val & 0xff);
  344. left = left + 0x32;
  345. /* 1111111 = +6dB, 0110000 = -73dB */
  346. if (right > 0x7f)
  347. right = 0x7f;
  348. if (right < 0x30)
  349. right = 0x30;
  350. if (left > 0x7f)
  351. left = 0x7f;
  352. if (left < 0x30)
  353. left = 0x30;
  354. switch (cmd) {
  355. case SOUND_MIXER_VOLUME: /* volume OUT1 */
  356. reg = wm8753_read_cache(WM8753_LOUT1V) & 0x180;
  357. wm8753_2w_write(&codec.wm_client, WM8753_LOUT1V,
  358. reg | left);
  359. reg = wm8753_read_cache(WM8753_ROUT1V) & 0x180;
  360. wm8753_2w_write(&codec.wm_client, WM8753_ROUT1V,
  361. reg | right);
  362. /* volume OUT2 */
  363. reg = wm8753_read_cache(WM8753_LOUT2V) & 0x180;
  364. wm8753_2w_write(&codec.wm_client, WM8753_LOUT2V,
  365. reg | left);
  366. reg = wm8753_read_cache(WM8753_ROUT2V) & 0x180;
  367. wm8753_2w_write(&codec.wm_client, WM8753_ROUT2V,
  368. reg | right);
  369. break;
  370. case SOUND_MIXER_BASS: /* bass */
  371. reg = wm8753_read_cache(WM8753_BASS) & 0x1f0;
  372. wm8753_2w_write(&codec.wm_client, WM8753_BASS,
  373. reg | (left & 0x0f));
  374. break;
  375. case SOUND_MIXER_TREBLE: /* treble */
  376. reg = wm8753_read_cache(WM8753_TREBLE) & 0x1f0;
  377. wm8753_2w_write(&codec.wm_client, WM8753_TREBLE,
  378. reg | (left & 0x0f));
  379. break;
  380. case SOUND_MIXER_SYNTH:
  381. break;
  382. case SOUND_MIXER_PCM:
  383. break;
  384. case SOUND_MIXER_SPEAKER: /* volume OUT2 */
  385. reg = wm8753_read_cache(WM8753_LOUT2V) & 0x180;
  386. wm8753_2w_write(&codec.wm_client, WM8753_LOUT2V,
  387. reg | left);
  388. reg = wm8753_read_cache(WM8753_ROUT2V) & 0x180;
  389. wm8753_2w_write(&codec.wm_client, WM8753_ROUT2V,
  390. reg | right);
  391. break;
  392. case SOUND_MIXER_LINE:
  393. break;
  394. case SOUND_MIXER_MIC:
  395. break;
  396. case SOUND_MIXER_CD:
  397. break;
  398. case SOUND_MIXER_IMIX: /* Recording monitor */
  399. break;
  400. case SOUND_MIXER_ALTPCM:
  401. break;
  402. case SOUND_MIXER_RECLEV: /* Recording level */
  403. break;
  404. case SOUND_MIXER_IGAIN: /* Input gain LR ADC */
  405. reg = wm8753_read_cache(WM8753_LADC) & 0x100;
  406. wm8753_2w_write(&codec.wm_client, WM8753_LADC, reg | left);
  407. reg = wm8753_read_cache(WM8753_RADC) & 0x100;
  408. wm8753_2w_write(&codec.wm_client, WM8753_RADC,
  409. reg | right);
  410. break;
  411. case SOUND_MIXER_OGAIN: /* Output gain LR DAC */
  412. reg = wm8753_read_cache(WM8753_LDAC) & 0x100;
  413. wm8753_2w_write(&codec.wm_client, WM8753_LDAC, reg | left);
  414. reg = wm8753_read_cache(WM8753_RDAC) & 0x100;
  415. wm8753_2w_write(&codec.wm_client, WM8753_RDAC,
  416. reg | right);
  417. break;
  418. default:
  419. DBG(KERN_WARNING "unknown mixer IOCTL");
  420. ret = -EINVAL;
  421. break;
  422. }
  423. return ret;
  424. }
  425. static int wm8753_mixer_ioctl(struct inode *inode, struct file *file,
  426. unsigned int cmd, unsigned long arg)
  427. {
  428. int i, val = 0;
  429. if (cmd == SOUND_MIXER_INFO) {
  430. mixer_info info;
  431. strncpy(info.id, codec.name, sizeof(info.id));
  432. strncpy(info.name, codec.name, sizeof(info.name));
  433. info.modify_counter = codec.modcnt;
  434. if (copy_to_user((void *) arg, &info, sizeof(info)))
  435. return -EFAULT;
  436. return 0;
  437. }
  438. if (cmd == SOUND_OLD_MIXER_INFO) {
  439. _old_mixer_info info;
  440. strncpy(info.id, codec.name, sizeof(info.id));
  441. strncpy(info.name, codec.name, sizeof(info.name));
  442. if (copy_to_user((void *) arg, &info, sizeof(info)))
  443. return -EFAULT;
  444. return 0;
  445. }
  446. if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int))
  447. return -EINVAL;
  448. if (cmd == OSS_GETVERSION)
  449. return put_user(SOUND_VERSION, (int *) arg);
  450. if (_SIOC_DIR(cmd) == _SIOC_READ) {
  451. switch (_IOC_NR(cmd)) {
  452. case SOUND_MIXER_DEVMASK: /* give them the supported mixers */
  453. val = codec.supported_mixers;
  454. break;
  455. case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */
  456. val = codec.record_sources;
  457. break;
  458. case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */
  459. val = codec.stereo_mixers;
  460. break;
  461. case SOUND_MIXER_CAPS:
  462. val = SOUND_CAP_EXCL_INPUT;
  463. break;
  464. default: /* read a specific mixer */
  465. i = _IOC_NR(cmd);
  466. if (!supported_mixer(&codec, i))
  467. return -EINVAL;
  468. val = wm8753_get_mixer(i);
  469. break;
  470. }
  471. return put_user(val, (int *) arg);
  472. }
  473. if (_SIOC_DIR(cmd) == (_SIOC_WRITE | _SIOC_READ)) {
  474. codec.modcnt++;
  475. if (get_user(val, (int *) arg))
  476. return -EFAULT;
  477. switch (_IOC_NR(cmd)) {
  478. default: /* write a specific mixer */
  479. i = _IOC_NR(cmd);
  480. if (!supported_mixer(&codec, i))
  481. return -EINVAL;
  482. return wm8753_set_mixer(i, val);
  483. }
  484. }
  485. return -EINVAL;
  486. }
  487. static struct file_operations wm8753_mixer_fops = {
  488. ioctl : wm8753_mixer_ioctl,
  489. llseek: no_llseek,
  490. owner : THIS_MODULE
  491. };
  492. static int wm8753_power_down(void)
  493. {
  494. if ((wm8753_2w_write(&codec.wm_client, WM8753_PWR1, 0x0100) != 0)
  495. && (wm8753_2w_write(&codec.wm_client, WM8753_PWR2, 0x0000) !=
  496. 0)
  497. && (wm8753_2w_write(&codec.wm_client, WM8753_PWR3, 0x0000) !=
  498. 0)
  499. && (wm8753_2w_write(&codec.wm_client, WM8753_PWR4, 0x0000) !=
  500. 0)) {
  501. DBG(KERN_ERR "could not powerdown WM8753");
  502. return -EIO;
  503. }
  504. return 0;
  505. }
  506. int wm8753_set_mic1_path(void)
  507. {
  508. /* ALCSEL : Left ch only, Set ALC target gain */
  509. if (wm8753_2w_write(&codec.wm_client, WM8753_ALC1, 0x017b) != 0)
  510. return -EIO;
  511. /* MICSEL : Mic1 selected */
  512. if (wm8753_2w_write(&codec.wm_client, WM8753_MICBIAS, 0x0000)
  513. != 0)
  514. return -EIO;
  515. /* MIC1ALC : ALC mix input select mic1 */
  516. if (wm8753_2w_write(&codec.wm_client, WM8753_INCTL2, 0x0002) != 0)
  517. return -EIO;
  518. /* RADCSEL : PGA, LADCSEL : PGA */
  519. if (wm8753_2w_write(&codec.wm_client, WM8753_ADCIN, 0x0000) != 0)
  520. return -EIO;
  521. /* 50k, VREF : on, MICB,VDAC : off, DACL,DACR : off, DIGENB : MCLK */
  522. if (wm8753_2w_write(&codec.wm_client, WM8753_PWR1, 0x00c0) != 0)
  523. return -EIO;
  524. /* MICAMP1EN,MICAMP2EN,ALCMIX,PGAL,PGAR,ADCL,ADCR : on, RXMIX,LINEMIX : off */
  525. if (wm8753_2w_write(&codec.wm_client, WM8753_PWR2, 0x01fc) != 0)
  526. return -EIO;
  527. return 0;
  528. }
  529. int wm8753_set_linein_path(void)
  530. {
  531. /* RADCSEL : LINE2, LADCSEL : LINE1 */
  532. if (wm8753_2w_write(&codec.wm_client, WM8753_ADCIN, 0x0015) != 0)
  533. return -EIO;
  534. /* ALCSEL : off */
  535. if (wm8753_2w_write(&codec.wm_client, WM8753_ALC1, 0x0000) != 0)
  536. return -EIO;
  537. /* RM : LINE2, LM : LINE1 */
  538. if (wm8753_2w_write(&codec.wm_client, WM8753_INCTL1, 0x0000) != 0)
  539. return -EIO;
  540. /* 50k, VREF : on, MICB,VDAC : off, DACL,DACR : off, DIGENB : MCLK */
  541. if (wm8753_2w_write(&codec.wm_client, WM8753_PWR1, 0x00c0) != 0)
  542. return -EIO;
  543. /* MICAMP1EN,MICAMP2EN,RXMIX,LINEMIX,ALCMIX,PGAL,PGAR : off, ADCL,ADCR : on */
  544. if (wm8753_2w_write(&codec.wm_client, WM8753_PWR2, 0x000c) != 0)
  545. return -EIO;
  546. return 0;
  547. }
  548. int wm8753_set_hpout_path(void)
  549. {
  550. /* LOUT1,ROUT1,LOUT2,ROUT2,OUT3,OUT4 : on, MONO1,2 : off */
  551. if (wm8753_2w_write(&codec.wm_client, WM8753_PWR3, 0x01f8) != 0)
  552. return -EIO;
  553. /* 50k, VREF : on, MICB,VDAC : off, DACL,DACR : on, DIGENB : MCLK */
  554. if (wm8753_2w_write(&codec.wm_client, WM8753_PWR1, 0x00cc) != 0)
  555. return -EIO;
  556. return 0;
  557. }
  558. /*
  559. * initiliase the WM8753
  560. */
  561. static int wm8753_init(void)
  562. {
  563. int ret = 0;
  564. /* power up the device */
  565. /* Reset all registers to their default value */
  566. ret += wm8753_2w_write(&codec.wm_client, WM8753_RESET, 0x0000);
  567. /* 5k divider en, VREF on, MICB off, VDAC off, DACL off, DACR off, MCLK dis */
  568. ret += wm8753_2w_write(&codec.wm_client, WM8753_PWR1, 0x01c1);
  569. /* Set Left DAC volume */
  570. ret += wm8753_2w_write(&codec.wm_client, WM8753_LDAC, 0x01ff);
  571. /* Set Right DAC volume */
  572. ret += wm8753_2w_write(&codec.wm_client, WM8753_RDAC, 0x01ff);
  573. /* Set Left OUT1 volume */
  574. ret += wm8753_2w_write(&codec.wm_client, WM8753_LOUT1V, 0x0179);
  575. /* Set Right OUT1 volume */
  576. ret += wm8753_2w_write(&codec.wm_client, WM8753_ROUT1V, 0x0179);
  577. /* Set Left OUT2 volume */
  578. ret += wm8753_2w_write(&codec.wm_client, WM8753_LOUT2V, 0x0179);
  579. /* Set Right OUT2 volume */
  580. ret += wm8753_2w_write(&codec.wm_client, WM8753_ROUT2V, 0x0179);
  581. /* Set Left input volume, Mute en */
  582. ret += wm8753_2w_write(&codec.wm_client, WM8753_LINVOL, 0x0197);
  583. /* Set Right input volume, Mute en */
  584. ret += wm8753_2w_write(&codec.wm_client, WM8753_RINVOL, 0x0197);
  585. /* Set Left ADC volume */
  586. ret += wm8753_2w_write(&codec.wm_client, WM8753_LADC, 0x01e8);
  587. /* Set Right ADC volume */
  588. ret += wm8753_2w_write(&codec.wm_client, WM8753_RADC, 0x01e8);
  589. /* LOUT1,ROUT1,LOUT2,ROUT2,MONO1,2 : off, OUT3,OUT4 : on */
  590. ret += wm8753_2w_write(&codec.wm_client, WM8753_PWR3, 0x0018);
  591. /* IFMODE : HiFi over HiFi, VXFS : out, LRCOE : out */
  592. ret += wm8753_2w_write(&codec.wm_client, WM8753_IOCTL, 0x000b);
  593. /* RADC input : LINE2, LADC input : LINE1 */
  594. ret += wm8753_2w_write(&codec.wm_client, WM8753_ADCIN, 0x0015);
  595. /* RDAC -> Right Mixer */
  596. ret += wm8753_2w_write(&codec.wm_client, WM8753_ROUTM1, 0x150);
  597. /* LDAC -> Left Mixer */
  598. ret += wm8753_2w_write(&codec.wm_client, WM8753_LOUTM1, 0x150);
  599. /* MCLKSEL : from MCLK pin, PCMCLKSEL : PCMCLK pin, CLKEQ : HiFi DAC */
  600. ret += wm8753_2w_write(&codec.wm_client, WM8753_CLOCK, 0x0004);
  601. /* HiFi audio interface : I2S format */
  602. ret += wm8753_2w_write(&codec.wm_client, WM8753_HIFI, 0x0002);
  603. /* PCM audio interface : I2S format */
  604. ret += wm8753_2w_write(&codec.wm_client, WM8753_PCM, 0x0002);
  605. /* VXDACOSR : 1, ADCOSR : 1, DACOSR : 1 */
  606. ret += wm8753_2w_write(&codec.wm_client, WM8753_SRATE2, 0x0007);
  607. /* IFMODE : HiFi over HiFi, VXFS : out, LRCOE : input */
  608. ret += wm8753_2w_write(&codec.wm_client, WM8753_IOCTL, 0x000a);
  609. /* 50k, VREF : on, MICB,VDAC : off, DACL,DACR : on, DIGENB : MCLK */
  610. ret += wm8753_2w_write(&codec.wm_client, WM8753_PWR1, 0x00cc);
  611. /* ADCL,ADCR : on, MICAPM1,2, ALCMIX,PGAL,PGAR,RXMIX,LINEMIX : off */
  612. ret += wm8753_2w_write(&codec.wm_client, WM8753_PWR2, 0x000c);
  613. /* LOUT1,ROUT1,LOUT2,ROUT2,OUT3,OUT4 : on, MONO1,2 : off */
  614. ret += wm8753_2w_write(&codec.wm_client, WM8753_PWR3, 0x01f8);
  615. /* RECMIX,MONOMIX : off, RIGHT MIX, LEFT MIX : on */
  616. ret += wm8753_2w_write(&codec.wm_client, WM8753_PWR4, 0x0003);
  617. ret += wm8753_2w_write(&codec.wm_client, WM8753_DAC, 0x0000);
  618. return ret != 0 ? -EIO : 0;
  619. }
  620. static int s3c_select_clk(void)
  621. {
  622. /* PCLK & SCLK gating enable */
  623. writel(readl(S3C_PCLK_GATE) | S3C_CLKCON_PCLK_IIS0, S3C_PCLK_GATE);
  624. writel(readl(S3C_SCLK_GATE) | S3C_CLKCON_SCLK_AUDIO0,
  625. S3C_SCLK_GATE);
  626. return 0;
  627. }
  628. /* open the WM8753 audio driver */
  629. static int s3c_audio_ioctl(struct inode *inode, struct file *file,
  630. uint cmd, ulong arg)
  631. {
  632. long val = 0;
  633. int ret = 0;
  634. audio_state_t *state = file->private_data;
  635. switch (cmd) {
  636. case SNDCTL_DSP_STEREO:
  637. if (get_user(val, (int *) arg))
  638. return -EINVAL;
  639. state->sound_mode = (val) ? 2 : 1;
  640. return 0;
  641. case SNDCTL_DSP_CHANNELS:
  642. if (get_user(val, (int *) arg))
  643. return -EINVAL;
  644. if (val != 1 && val != 2)
  645. return -EINVAL;
  646. state->sound_mode = val;
  647. return put_user(val, (int *) arg);
  648. case SOUND_PCM_READ_CHANNELS:
  649. return put_user(state->sound_mode, (long *) arg);
  650. case SNDCTL_DSP_SPEED:
  651. ret = get_user(val, (long *) arg);
  652. if (ret)
  653. break;
  654. audio_set_dsp_speed(val);
  655. switch (val) {
  656. case 8000:
  657. case 16000:
  658. case 32000:
  659. wm8753_2w_write(&codec.wm_client, WM8753_SRATE1,
  660. 0x0018);
  661. break;
  662. case 11025:
  663. case 22050:
  664. case 44100:
  665. wm8753_2w_write(&codec.wm_client, WM8753_SRATE1,
  666. 0x0022);
  667. break;
  668. case 48000:
  669. wm8753_2w_write(&codec.wm_client, WM8753_SRATE1,
  670. 0x000a);
  671. break;
  672. }
  673. break;
  674. case SOUND_PCM_READ_RATE:
  675. ret = put_user(val, (long *) arg);
  676. break;
  677. case SNDCTL_DSP_SETFMT:
  678. case SNDCTL_DSP_GETFMTS:
  679. /* we can do 16-bit only */
  680. ret = put_user(AFMT_S16_LE, (long *) arg);
  681. break;
  682. default:
  683. /* Maybe this is meant for the mixer (as per OSS Docs) */
  684. ret = wm8753_mixer_ioctl(inode, file, cmd, arg);
  685. break;
  686. }
  687. return ret;
  688. }
  689. static void s3c_audio_shutdown(void *dummy)
  690. {
  691. unsigned long iismod, iiscon;
  692. iismod = readl(S3C_IIS0MOD);
  693. iismod &= ~S3C_IIS0MOD_TXMODE;
  694. iismod &= ~S3C_IIS0MOD_RXMODE;
  695. writel(iismod, S3C_IIS0MOD);
  696. iiscon = readl(S3C_IIS0CON);
  697. if (iismod & (S3C_IIS0MOD_TXMODE | S3C_IIS0MOD_RXMODE)) {
  698. iiscon &= !S3C_IIS0CON_I2SACTIVE;
  699. writel(iiscon, S3C_IIS0CON);
  700. }
  701. /* Disable the I2S clock */
  702. writel(readl(S3C_PCLK_GATE) & ~(S3C_CLKCON_PCLK_IIS0),
  703. S3C_PCLK_GATE);
  704. writel(readl(S3C_SCLK_GATE) & ~(S3C_CLKCON_SCLK_AUDIO0),
  705. S3C_SCLK_GATE);
  706. writel(readl(S3C_EPLL_CON0) & ~(1 << 31), S3C_EPLL_CON0);
  707. }
  708. static int s3c_init_iis(void)
  709. {
  710. /*Set I2C port to controll WM8753 codec */
  711. s3c_gpio_pullup(S3C_GPB5, 0);
  712. s3c_gpio_pullup(S3C_GPB6, 0);
  713. s3c_gpio_cfgpin(S3C_GPB5, S3C_GPB5_I2C_SCL);
  714. s3c_gpio_cfgpin(S3C_GPB6, S3C_GPB6_I2C_SDA);
  715. s3c_gpio_cfgpin(S3C_GPD0, S3C_GPD0_I2S_CLK0);
  716. s3c_gpio_cfgpin(S3C_GPD1, S3C_GPD1_I2S_CDCLK0);
  717. s3c_gpio_cfgpin(S3C_GPD2, S3C_GPD2_I2S_LRCLK0);
  718. s3c_gpio_cfgpin(S3C_GPD3, S3C_GPD3_I2S_DI0);
  719. s3c_gpio_cfgpin(S3C_GPD4, S3C_GPD4_I2S_DO0);
  720. s3c_gpio_pullup(S3C_GPD0, 2);
  721. s3c_gpio_pullup(S3C_GPD1, 2);
  722. s3c_gpio_pullup(S3C_GPD2, 2);
  723. s3c_gpio_pullup(S3C_GPD3, 2);
  724. s3c_gpio_pullup(S3C_GPD4, 2);
  725. return 0;
  726. }
  727. static audio_stream_t output_stream = {
  728. id: "s3c64xx audio out ",
  729. subchannel: DMACH_I2S_OUT,
  730. };
  731. static audio_stream_t input_stream = {
  732. id: "s3c64xx audio in ",
  733. subchannel: DMACH_I2S_IN,
  734. };
  735. static audio_state_t audio_state = {
  736. .output_stream = &output_stream,
  737. .input_stream = &input_stream,
  738. .hw_shutdown = s3c_audio_shutdown,
  739. .client_ioctl = s3c_audio_ioctl,
  740. };
  741. static int wm8753_hifi_open(struct inode *inode, struct file *file)
  742. {
  743. s3c_init_iis();
  744. s3c_select_clk();
  745. init_MUTEX(&audio_state.sem);
  746. return s3c_audio_attach(inode, file, &audio_state);
  747. }
  748. static struct file_operations wm8753_hifi_fops = {
  749. open : wm8753_hifi_open,
  750. owner: THIS_MODULE
  751. };
  752. /*
  753. * reset the WM8753
  754. */
  755. static inline int wm8753_reset(struct i2c_client *client)
  756. {
  757. return wm8753_2w_write(client, WM8753_RESET, 0);
  758. }
  759. /* WM8753 2 Wire layer */
  760. static int wm8753_attach_adapter(struct i2c_adapter *adapter);
  761. static int wm8753_detach_client(struct i2c_client *client);
  762. static struct i2c_driver wm_driver = {
  763. .driver = {
  764. .name = "wm8753",
  765. .owner = THIS_MODULE,},
  766. .id = I2C_DRIVERID_WM8753,
  767. .attach_adapter = wm8753_attach_adapter,
  768. .detach_client = wm8753_detach_client,
  769. };
  770. static int wm8753_detect(struct i2c_adapter *adap, int addr, int kind)
  771. {
  772. int ret;
  773. i2c_set_clientdata(&codec.wm_client, &codec);
  774. codec.wm_client.addr = addr;
  775. codec.wm_client.adapter = adap;
  776. codec.wm_client.driver = &wm_driver;
  777. codec.wm_client.flags = 0;
  778. /* since the codec is read only, we have to assume that a successful
  779. * write (via a codec reset) is proof that the codec is responding
  780. */
  781. if (wm8753_reset(&codec.wm_client) != 0) {
  782. printk(KERN_ERR "cannot reset the WM8753");
  783. complete(&codec.i2c_init);
  784. return -EIO;
  785. }
  786. strlcpy(codec.wm_client.name, "wm8753", I2C_NAME_SIZE);
  787. if ((ret = i2c_attach_client(&codec.wm_client)) == 0)
  788. codec.wm8753_valid = 1;
  789. complete(&codec.i2c_init);
  790. return ret;
  791. }
  792. //static int wm8753_attach_adapter(struct i2c_adapter *adapter)
  793. static int wm8753_attach_adapter(struct i2c_adapter *adap)
  794. {
  795. return i2c_probe(adap, &addr_data, wm8753_detect);
  796. //return i2c_probe(adapter, &addr_data, wm8753_detect);
  797. }
  798. /*
  799. * Detach WM8753 2 wire client
  800. */
  801. static int wm8753_detach_client(struct i2c_client *client)
  802. {
  803. i2c_detach_client(client);
  804. return 0;
  805. }
  806. static int s3c_i2s_init(void)
  807. {
  808. init_completion(&codec.i2c_init);
  809. if (i2c_add_driver(&wm_driver)) {
  810. printk(KERN_ERR "can't add i2c driver\n");
  811. goto err_dev;
  812. }
  813. /* wait for i2c init to complete */
  814. wait_for_completion(&codec.i2c_init);
  815. if (!codec.wm8753_valid) {
  816. printk(KERN_ERR "can't find codec\n");
  817. goto err_dev;
  818. }
  819. /* initialise WM8753 */
  820. if (wm8753_init() != 0) {
  821. printk(KERN_ERR "can't initialise WM8753\n");
  822. goto err_io;
  823. }
  824. return 0;
  825. err_dev:
  826. return -ENODEV;
  827. err_io:
  828. i2c_del_driver(&wm_driver);
  829. return -EIO;
  830. }
  831. #ifdef CONFIG_PM
  832. /* TODO : Power management */
  833. int s3c64xx_i2s_suspend(void)
  834. {
  835. return 0;
  836. }
  837. int s3c64xx_i2s_resume(void)
  838. {
  839. return 0;
  840. }
  841. static int s3c64xx_pm_callback(struct pm_dev *dev, pm_request_t rqst,
  842. void *data)
  843. {
  844. switch (rqst) {
  845. case PM_SUSPEND:
  846. s3c64xx_i2s_suspend();
  847. break;
  848. case PM_RESUME:
  849. s3c64xx_i2s_resume();
  850. break;
  851. }
  852. return 0;
  853. }
  854. #else /* */
  855. #define s3c64xx_i2s_suspend NULL
  856. #define s3c64xx_i2s_resume NULL
  857. #endif /* */
  858. static int audio_dev_id, mixer_dev_id;
  859. static int s3c64xx_audio_probe(struct device *dev)
  860. {
  861. s3c_i2s_init();
  862. audio_dev_id = register_sound_dsp(&wm8753_hifi_fops, -1);
  863. mixer_dev_id = register_sound_mixer(&wm8753_mixer_fops, -1);
  864. printk(KERN_INFO "Sound: S3C-I2S: dsp id %d mixer id %d\n",
  865. audio_dev_id, mixer_dev_id);
  866. flush_scheduled_work();
  867. #ifdef CONFIG_PM
  868. pm_register(PM_SYS_DEV, PM_SYS_UNKNOWN, s3c64xx_pm_callback);
  869. #endif /* */
  870. return 0;
  871. }
  872. static int s3c64xx_audio_remove(struct device *dev)
  873. {
  874. wm8753_power_down();
  875. unregister_sound_dsp(audio_dev_id);
  876. unregister_sound_mixer(mixer_dev_id);
  877. i2c_del_driver(&wm_driver);
  878. return 0;
  879. }
  880. static struct device_driver s3c64xx_i2s_driver = {
  881. .name = "s3c2410-iis",
  882. .bus = &platform_bus_type,
  883. .probe = s3c64xx_audio_probe,
  884. .remove = s3c64xx_audio_remove,
  885. #ifdef CONFIG_PM
  886. .suspend = s3c64xx_audio_suspend,
  887. .resume = s3c64xx_audio_resume,
  888. #endif
  889. };
  890. /*
  891. * initialise the WM8753 driver
  892. * register the mixer and dsp interfaces with the kernel
  893. */
  894. static int __init s3c_wm8753_init(void)
  895. {
  896. return driver_register(&s3c64xx_i2s_driver);
  897. }
  898. module_init(s3c_wm8753_init);
  899. /*
  900. * unregister interfaces and clean up
  901. */
  902. static void __exit s3c_wm8753_exit(void)
  903. {
  904. driver_unregister(&s3c64xx_i2s_driver);
  905. }
  906. module_exit(s3c_wm8753_exit);
  907. MODULE_AUTHOR("Ryu Euiyoul");
  908. MODULE_DESCRIPTION("Samsung S3C WM8753 driver");
  909. MODULE_LICENSE("GPL");