tas3001c.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850
  1. /*
  2. * Driver for the i2c/i2s based TA3004 sound chip used
  3. * on some Apple hardware. Also known as "snapper".
  4. *
  5. * Tobias Sargeant <tobias.sargeant@bigpond.com>
  6. * Based upon, tas3001c.c by Christopher C. Chimelis <chris@debian.org>:
  7. *
  8. * TODO:
  9. * -----
  10. * * Enable control over input line 2 (is this connected?)
  11. * * Implement sleep support (at least mute everything and
  12. * * set gains to minimum during sleep)
  13. * * Look into some of Darwin's tweaks regarding the mute
  14. * * lines (delays & different behaviour on some HW)
  15. *
  16. */
  17. #include <linux/module.h>
  18. #include <linux/slab.h>
  19. #include <linux/proc_fs.h>
  20. #include <linux/ioport.h>
  21. #include <linux/sysctl.h>
  22. #include <linux/types.h>
  23. #include <linux/i2c.h>
  24. #include <linux/init.h>
  25. #include <linux/soundcard.h>
  26. #include <linux/workqueue.h>
  27. #include <asm/uaccess.h>
  28. #include <asm/errno.h>
  29. #include <asm/io.h>
  30. #include <asm/prom.h>
  31. #include "dmasound.h"
  32. #include "tas_common.h"
  33. #include "tas3001c.h"
  34. #include "tas_ioctl.h"
  35. #define TAS3001C_BIQUAD_FILTER_COUNT 6
  36. #define TAS3001C_BIQUAD_CHANNEL_COUNT 2
  37. #define VOL_DEFAULT (100 * 4 / 5)
  38. #define INPUT_DEFAULT (100 * 4 / 5)
  39. #define BASS_DEFAULT (100 / 2)
  40. #define TREBLE_DEFAULT (100 / 2)
  41. struct tas3001c_data_t {
  42. struct tas_data_t super;
  43. int device_id;
  44. int output_id;
  45. int speaker_id;
  46. struct tas_drce_t drce_state;
  47. };
  48. static const union tas_biquad_t
  49. tas3001c_eq_unity={
  50. .buf = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 }
  51. };
  52. static inline unsigned char db_to_regval(short db) {
  53. int r=0;
  54. r=(db+0x59a0) / 0x60;
  55. if (r < 0x91) return 0x91;
  56. if (r > 0xef) return 0xef;
  57. return r;
  58. }
  59. static inline short quantize_db(short db) {
  60. return db_to_regval(db) * 0x60 - 0x59a0;
  61. }
  62. static inline int
  63. register_width(enum tas3001c_reg_t r)
  64. {
  65. switch(r) {
  66. case TAS3001C_REG_MCR:
  67. case TAS3001C_REG_TREBLE:
  68. case TAS3001C_REG_BASS:
  69. return 1;
  70. case TAS3001C_REG_DRC:
  71. return 2;
  72. case TAS3001C_REG_MIXER1:
  73. case TAS3001C_REG_MIXER2:
  74. return 3;
  75. case TAS3001C_REG_VOLUME:
  76. return 6;
  77. case TAS3001C_REG_LEFT_BIQUAD0:
  78. case TAS3001C_REG_LEFT_BIQUAD1:
  79. case TAS3001C_REG_LEFT_BIQUAD2:
  80. case TAS3001C_REG_LEFT_BIQUAD3:
  81. case TAS3001C_REG_LEFT_BIQUAD4:
  82. case TAS3001C_REG_LEFT_BIQUAD5:
  83. case TAS3001C_REG_LEFT_BIQUAD6:
  84. case TAS3001C_REG_RIGHT_BIQUAD0:
  85. case TAS3001C_REG_RIGHT_BIQUAD1:
  86. case TAS3001C_REG_RIGHT_BIQUAD2:
  87. case TAS3001C_REG_RIGHT_BIQUAD3:
  88. case TAS3001C_REG_RIGHT_BIQUAD4:
  89. case TAS3001C_REG_RIGHT_BIQUAD5:
  90. case TAS3001C_REG_RIGHT_BIQUAD6:
  91. return 15;
  92. default:
  93. return 0;
  94. }
  95. }
  96. static int
  97. tas3001c_write_register( struct tas3001c_data_t *self,
  98. enum tas3001c_reg_t reg_num,
  99. char *data,
  100. uint write_mode)
  101. {
  102. if (reg_num==TAS3001C_REG_MCR ||
  103. reg_num==TAS3001C_REG_BASS ||
  104. reg_num==TAS3001C_REG_TREBLE) {
  105. return tas_write_byte_register(&self->super,
  106. (uint)reg_num,
  107. *data,
  108. write_mode);
  109. } else {
  110. return tas_write_register(&self->super,
  111. (uint)reg_num,
  112. register_width(reg_num),
  113. data,
  114. write_mode);
  115. }
  116. }
  117. static int
  118. tas3001c_sync_register( struct tas3001c_data_t *self,
  119. enum tas3001c_reg_t reg_num)
  120. {
  121. if (reg_num==TAS3001C_REG_MCR ||
  122. reg_num==TAS3001C_REG_BASS ||
  123. reg_num==TAS3001C_REG_TREBLE) {
  124. return tas_sync_byte_register(&self->super,
  125. (uint)reg_num,
  126. register_width(reg_num));
  127. } else {
  128. return tas_sync_register(&self->super,
  129. (uint)reg_num,
  130. register_width(reg_num));
  131. }
  132. }
  133. static int
  134. tas3001c_read_register( struct tas3001c_data_t *self,
  135. enum tas3001c_reg_t reg_num,
  136. char *data,
  137. uint write_mode)
  138. {
  139. return tas_read_register(&self->super,
  140. (uint)reg_num,
  141. register_width(reg_num),
  142. data);
  143. }
  144. static inline int
  145. tas3001c_fast_load(struct tas3001c_data_t *self, int fast)
  146. {
  147. if (fast)
  148. self->super.shadow[TAS3001C_REG_MCR][0] |= 0x80;
  149. else
  150. self->super.shadow[TAS3001C_REG_MCR][0] &= 0x7f;
  151. return tas3001c_sync_register(self,TAS3001C_REG_MCR);
  152. }
  153. static uint
  154. tas3001c_supported_mixers(struct tas3001c_data_t *self)
  155. {
  156. return SOUND_MASK_VOLUME |
  157. SOUND_MASK_PCM |
  158. SOUND_MASK_ALTPCM |
  159. SOUND_MASK_TREBLE |
  160. SOUND_MASK_BASS;
  161. }
  162. static int
  163. tas3001c_mixer_is_stereo(struct tas3001c_data_t *self,int mixer)
  164. {
  165. switch(mixer) {
  166. case SOUND_MIXER_VOLUME:
  167. return 1;
  168. default:
  169. return 0;
  170. }
  171. }
  172. static uint
  173. tas3001c_stereo_mixers(struct tas3001c_data_t *self)
  174. {
  175. uint r=tas3001c_supported_mixers(self);
  176. uint i;
  177. for (i=1; i<SOUND_MIXER_NRDEVICES; i++)
  178. if (r&(1<<i) && !tas3001c_mixer_is_stereo(self,i))
  179. r &= ~(1<<i);
  180. return r;
  181. }
  182. static int
  183. tas3001c_get_mixer_level(struct tas3001c_data_t *self,int mixer,uint *level)
  184. {
  185. if (!self)
  186. return -1;
  187. *level=self->super.mixer[mixer];
  188. return 0;
  189. }
  190. static int
  191. tas3001c_set_mixer_level(struct tas3001c_data_t *self,int mixer,uint level)
  192. {
  193. int rc;
  194. tas_shadow_t *shadow;
  195. uint temp;
  196. uint offset=0;
  197. if (!self)
  198. return -1;
  199. shadow=self->super.shadow;
  200. if (!tas3001c_mixer_is_stereo(self,mixer))
  201. level = tas_mono_to_stereo(level);
  202. switch(mixer) {
  203. case SOUND_MIXER_VOLUME:
  204. temp = tas3001c_gain.master[level&0xff];
  205. shadow[TAS3001C_REG_VOLUME][0] = (temp >> 16) & 0xff;
  206. shadow[TAS3001C_REG_VOLUME][1] = (temp >> 8) & 0xff;
  207. shadow[TAS3001C_REG_VOLUME][2] = (temp >> 0) & 0xff;
  208. temp = tas3001c_gain.master[(level>>8)&0xff];
  209. shadow[TAS3001C_REG_VOLUME][3] = (temp >> 16) & 0xff;
  210. shadow[TAS3001C_REG_VOLUME][4] = (temp >> 8) & 0xff;
  211. shadow[TAS3001C_REG_VOLUME][5] = (temp >> 0) & 0xff;
  212. rc = tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
  213. break;
  214. case SOUND_MIXER_ALTPCM:
  215. /* tas3001c_fast_load(self, 1); */
  216. level = tas_mono_to_stereo(level);
  217. temp = tas3001c_gain.mixer[level&0xff];
  218. shadow[TAS3001C_REG_MIXER2][offset+0] = (temp >> 16) & 0xff;
  219. shadow[TAS3001C_REG_MIXER2][offset+1] = (temp >> 8) & 0xff;
  220. shadow[TAS3001C_REG_MIXER2][offset+2] = (temp >> 0) & 0xff;
  221. rc = tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
  222. /* tas3001c_fast_load(self, 0); */
  223. break;
  224. case SOUND_MIXER_PCM:
  225. /* tas3001c_fast_load(self, 1); */
  226. level = tas_mono_to_stereo(level);
  227. temp = tas3001c_gain.mixer[level&0xff];
  228. shadow[TAS3001C_REG_MIXER1][offset+0] = (temp >> 16) & 0xff;
  229. shadow[TAS3001C_REG_MIXER1][offset+1] = (temp >> 8) & 0xff;
  230. shadow[TAS3001C_REG_MIXER1][offset+2] = (temp >> 0) & 0xff;
  231. rc = tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
  232. /* tas3001c_fast_load(self, 0); */
  233. break;
  234. case SOUND_MIXER_TREBLE:
  235. temp = tas3001c_gain.treble[level&0xff];
  236. shadow[TAS3001C_REG_TREBLE][0]=temp&0xff;
  237. rc = tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
  238. break;
  239. case SOUND_MIXER_BASS:
  240. temp = tas3001c_gain.bass[level&0xff];
  241. shadow[TAS3001C_REG_BASS][0]=temp&0xff;
  242. rc = tas3001c_sync_register(self,TAS3001C_REG_BASS);
  243. break;
  244. default:
  245. rc = -1;
  246. break;
  247. }
  248. if (rc < 0)
  249. return rc;
  250. self->super.mixer[mixer]=level;
  251. return 0;
  252. }
  253. static int
  254. tas3001c_leave_sleep(struct tas3001c_data_t *self)
  255. {
  256. unsigned char mcr = (1<<6)+(2<<4)+(2<<2);
  257. if (!self)
  258. return -1;
  259. /* Make sure something answers on the i2c bus */
  260. if (tas3001c_write_register(self, TAS3001C_REG_MCR, &mcr,
  261. WRITE_NORMAL|FORCE_WRITE) < 0)
  262. return -1;
  263. tas3001c_fast_load(self, 1);
  264. (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD0);
  265. (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD1);
  266. (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD2);
  267. (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD3);
  268. (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD4);
  269. (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD5);
  270. (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD0);
  271. (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD1);
  272. (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD2);
  273. (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD3);
  274. (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD4);
  275. (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD5);
  276. tas3001c_fast_load(self, 0);
  277. (void)tas3001c_sync_register(self,TAS3001C_REG_BASS);
  278. (void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
  279. (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
  280. (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
  281. (void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
  282. return 0;
  283. }
  284. static int
  285. tas3001c_enter_sleep(struct tas3001c_data_t *self)
  286. {
  287. /* Stub for now, but I have the details on low-power mode */
  288. if (!self)
  289. return -1;
  290. return 0;
  291. }
  292. static int
  293. tas3001c_sync_biquad( struct tas3001c_data_t *self,
  294. u_int channel,
  295. u_int filter)
  296. {
  297. enum tas3001c_reg_t reg;
  298. if (channel >= TAS3001C_BIQUAD_CHANNEL_COUNT ||
  299. filter >= TAS3001C_BIQUAD_FILTER_COUNT) return -EINVAL;
  300. reg=( channel ? TAS3001C_REG_RIGHT_BIQUAD0 : TAS3001C_REG_LEFT_BIQUAD0 ) + filter;
  301. return tas3001c_sync_register(self,reg);
  302. }
  303. static int
  304. tas3001c_write_biquad_shadow( struct tas3001c_data_t *self,
  305. u_int channel,
  306. u_int filter,
  307. const union tas_biquad_t *biquad)
  308. {
  309. tas_shadow_t *shadow=self->super.shadow;
  310. enum tas3001c_reg_t reg;
  311. if (channel >= TAS3001C_BIQUAD_CHANNEL_COUNT ||
  312. filter >= TAS3001C_BIQUAD_FILTER_COUNT) return -EINVAL;
  313. reg=( channel ? TAS3001C_REG_RIGHT_BIQUAD0 : TAS3001C_REG_LEFT_BIQUAD0 ) + filter;
  314. SET_4_20(shadow[reg], 0,biquad->coeff.b0);
  315. SET_4_20(shadow[reg], 3,biquad->coeff.b1);
  316. SET_4_20(shadow[reg], 6,biquad->coeff.b2);
  317. SET_4_20(shadow[reg], 9,biquad->coeff.a1);
  318. SET_4_20(shadow[reg],12,biquad->coeff.a2);
  319. return 0;
  320. }
  321. static int
  322. tas3001c_write_biquad( struct tas3001c_data_t *self,
  323. u_int channel,
  324. u_int filter,
  325. const union tas_biquad_t *biquad)
  326. {
  327. int rc;
  328. rc=tas3001c_write_biquad_shadow(self, channel, filter, biquad);
  329. if (rc < 0) return rc;
  330. return tas3001c_sync_biquad(self, channel, filter);
  331. }
  332. static int
  333. tas3001c_write_biquad_list( struct tas3001c_data_t *self,
  334. u_int filter_count,
  335. u_int flags,
  336. struct tas_biquad_ctrl_t *biquads)
  337. {
  338. int i;
  339. int rc;
  340. if (flags & TAS_BIQUAD_FAST_LOAD) tas3001c_fast_load(self,1);
  341. for (i=0; i<filter_count; i++) {
  342. rc=tas3001c_write_biquad(self,
  343. biquads[i].channel,
  344. biquads[i].filter,
  345. &biquads[i].data);
  346. if (rc < 0) break;
  347. }
  348. if (flags & TAS_BIQUAD_FAST_LOAD) {
  349. tas3001c_fast_load(self,0);
  350. (void)tas3001c_sync_register(self,TAS3001C_REG_BASS);
  351. (void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
  352. (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
  353. (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
  354. (void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
  355. }
  356. return rc;
  357. }
  358. static int
  359. tas3001c_read_biquad( struct tas3001c_data_t *self,
  360. u_int channel,
  361. u_int filter,
  362. union tas_biquad_t *biquad)
  363. {
  364. tas_shadow_t *shadow=self->super.shadow;
  365. enum tas3001c_reg_t reg;
  366. if (channel >= TAS3001C_BIQUAD_CHANNEL_COUNT ||
  367. filter >= TAS3001C_BIQUAD_FILTER_COUNT) return -EINVAL;
  368. reg=( channel ? TAS3001C_REG_RIGHT_BIQUAD0 : TAS3001C_REG_LEFT_BIQUAD0 ) + filter;
  369. biquad->coeff.b0=GET_4_20(shadow[reg], 0);
  370. biquad->coeff.b1=GET_4_20(shadow[reg], 3);
  371. biquad->coeff.b2=GET_4_20(shadow[reg], 6);
  372. biquad->coeff.a1=GET_4_20(shadow[reg], 9);
  373. biquad->coeff.a2=GET_4_20(shadow[reg],12);
  374. return 0;
  375. }
  376. static int
  377. tas3001c_eq_rw( struct tas3001c_data_t *self,
  378. u_int cmd,
  379. u_long arg)
  380. {
  381. int rc;
  382. struct tas_biquad_ctrl_t biquad;
  383. void __user *argp = (void __user *)arg;
  384. if (copy_from_user(&biquad, argp, sizeof(struct tas_biquad_ctrl_t))) {
  385. return -EFAULT;
  386. }
  387. if (cmd & SIOC_IN) {
  388. rc=tas3001c_write_biquad(self, biquad.channel, biquad.filter, &biquad.data);
  389. if (rc != 0) return rc;
  390. }
  391. if (cmd & SIOC_OUT) {
  392. rc=tas3001c_read_biquad(self, biquad.channel, biquad.filter, &biquad.data);
  393. if (rc != 0) return rc;
  394. if (copy_to_user(argp, &biquad, sizeof(struct tas_biquad_ctrl_t))) {
  395. return -EFAULT;
  396. }
  397. }
  398. return 0;
  399. }
  400. static int
  401. tas3001c_eq_list_rw( struct tas3001c_data_t *self,
  402. u_int cmd,
  403. u_long arg)
  404. {
  405. int rc;
  406. int filter_count;
  407. int flags;
  408. int i,j;
  409. char sync_required[2][6];
  410. struct tas_biquad_ctrl_t biquad;
  411. struct tas_biquad_ctrl_list_t __user *argp = (void __user *)arg;
  412. memset(sync_required,0,sizeof(sync_required));
  413. if (copy_from_user(&filter_count, &argp->filter_count, sizeof(int)))
  414. return -EFAULT;
  415. if (copy_from_user(&flags, &argp->flags, sizeof(int)))
  416. return -EFAULT;
  417. if (cmd & SIOC_IN) {
  418. }
  419. for (i=0; i < filter_count; i++) {
  420. if (copy_from_user(&biquad, &argp->biquads[i],
  421. sizeof(struct tas_biquad_ctrl_t))) {
  422. return -EFAULT;
  423. }
  424. if (cmd & SIOC_IN) {
  425. sync_required[biquad.channel][biquad.filter]=1;
  426. rc=tas3001c_write_biquad_shadow(self, biquad.channel, biquad.filter, &biquad.data);
  427. if (rc != 0) return rc;
  428. }
  429. if (cmd & SIOC_OUT) {
  430. rc=tas3001c_read_biquad(self, biquad.channel, biquad.filter, &biquad.data);
  431. if (rc != 0) return rc;
  432. if (copy_to_user(&argp->biquads[i], &biquad,
  433. sizeof(struct tas_biquad_ctrl_t))) {
  434. return -EFAULT;
  435. }
  436. }
  437. }
  438. if (cmd & SIOC_IN) {
  439. if (flags & TAS_BIQUAD_FAST_LOAD) tas3001c_fast_load(self,1);
  440. for (i=0; i<2; i++) {
  441. for (j=0; j<6; j++) {
  442. if (sync_required[i][j]) {
  443. rc=tas3001c_sync_biquad(self, i, j);
  444. if (rc < 0) return rc;
  445. }
  446. }
  447. }
  448. if (flags & TAS_BIQUAD_FAST_LOAD) {
  449. tas3001c_fast_load(self,0);
  450. /* now we need to set up the mixers again,
  451. because leaving fast mode resets them. */
  452. (void)tas3001c_sync_register(self,TAS3001C_REG_BASS);
  453. (void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
  454. (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
  455. (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
  456. (void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
  457. }
  458. }
  459. return 0;
  460. }
  461. static int
  462. tas3001c_update_drce( struct tas3001c_data_t *self,
  463. int flags,
  464. struct tas_drce_t *drce)
  465. {
  466. tas_shadow_t *shadow;
  467. shadow=self->super.shadow;
  468. shadow[TAS3001C_REG_DRC][1] = 0xc1;
  469. if (flags & TAS_DRCE_THRESHOLD) {
  470. self->drce_state.threshold=quantize_db(drce->threshold);
  471. shadow[TAS3001C_REG_DRC][2] = db_to_regval(self->drce_state.threshold);
  472. }
  473. if (flags & TAS_DRCE_ENABLE) {
  474. self->drce_state.enable = drce->enable;
  475. }
  476. if (!self->drce_state.enable) {
  477. shadow[TAS3001C_REG_DRC][0] = 0xf0;
  478. }
  479. #ifdef DEBUG_DRCE
  480. printk("DRCE IOCTL: set [ ENABLE:%x THRESH:%x\n",
  481. self->drce_state.enable,
  482. self->drce_state.threshold);
  483. printk("DRCE IOCTL: reg [ %02x %02x ]\n",
  484. (unsigned char)shadow[TAS3001C_REG_DRC][0],
  485. (unsigned char)shadow[TAS3001C_REG_DRC][1]);
  486. #endif
  487. return tas3001c_sync_register(self, TAS3001C_REG_DRC);
  488. }
  489. static int
  490. tas3001c_drce_rw( struct tas3001c_data_t *self,
  491. u_int cmd,
  492. u_long arg)
  493. {
  494. int rc;
  495. struct tas_drce_ctrl_t drce_ctrl;
  496. void __user *argp = (void __user *)arg;
  497. if (copy_from_user(&drce_ctrl, argp, sizeof(struct tas_drce_ctrl_t)))
  498. return -EFAULT;
  499. #ifdef DEBUG_DRCE
  500. printk("DRCE IOCTL: input [ FLAGS:%x ENABLE:%x THRESH:%x\n",
  501. drce_ctrl.flags,
  502. drce_ctrl.data.enable,
  503. drce_ctrl.data.threshold);
  504. #endif
  505. if (cmd & SIOC_IN) {
  506. rc = tas3001c_update_drce(self, drce_ctrl.flags, &drce_ctrl.data);
  507. if (rc < 0)
  508. return rc;
  509. }
  510. if (cmd & SIOC_OUT) {
  511. if (drce_ctrl.flags & TAS_DRCE_ENABLE)
  512. drce_ctrl.data.enable = self->drce_state.enable;
  513. if (drce_ctrl.flags & TAS_DRCE_THRESHOLD)
  514. drce_ctrl.data.threshold = self->drce_state.threshold;
  515. if (copy_to_user(argp, &drce_ctrl,
  516. sizeof(struct tas_drce_ctrl_t))) {
  517. return -EFAULT;
  518. }
  519. }
  520. return 0;
  521. }
  522. static void
  523. tas3001c_update_device_parameters(struct tas3001c_data_t *self)
  524. {
  525. int i,j;
  526. if (!self) return;
  527. if (self->output_id == TAS_OUTPUT_HEADPHONES) {
  528. tas3001c_fast_load(self, 1);
  529. for (i=0; i<TAS3001C_BIQUAD_CHANNEL_COUNT; i++) {
  530. for (j=0; j<TAS3001C_BIQUAD_FILTER_COUNT; j++) {
  531. tas3001c_write_biquad(self, i, j, &tas3001c_eq_unity);
  532. }
  533. }
  534. tas3001c_fast_load(self, 0);
  535. (void)tas3001c_sync_register(self,TAS3001C_REG_BASS);
  536. (void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
  537. (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
  538. (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
  539. (void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
  540. return;
  541. }
  542. for (i=0; tas3001c_eq_prefs[i]; i++) {
  543. struct tas_eq_pref_t *eq = tas3001c_eq_prefs[i];
  544. if (eq->device_id == self->device_id &&
  545. (eq->output_id == 0 || eq->output_id == self->output_id) &&
  546. (eq->speaker_id == 0 || eq->speaker_id == self->speaker_id)) {
  547. tas3001c_update_drce(self, TAS_DRCE_ALL, eq->drce);
  548. tas3001c_write_biquad_list(self, eq->filter_count, TAS_BIQUAD_FAST_LOAD, eq->biquads);
  549. break;
  550. }
  551. }
  552. }
  553. static void
  554. tas3001c_device_change_handler(void *self)
  555. {
  556. if (self)
  557. tas3001c_update_device_parameters(self);
  558. }
  559. static struct work_struct device_change;
  560. static int
  561. tas3001c_output_device_change( struct tas3001c_data_t *self,
  562. int device_id,
  563. int output_id,
  564. int speaker_id)
  565. {
  566. self->device_id=device_id;
  567. self->output_id=output_id;
  568. self->speaker_id=speaker_id;
  569. schedule_work(&device_change);
  570. return 0;
  571. }
  572. static int
  573. tas3001c_device_ioctl( struct tas3001c_data_t *self,
  574. u_int cmd,
  575. u_long arg)
  576. {
  577. uint __user *argp = (void __user *)arg;
  578. switch (cmd) {
  579. case TAS_READ_EQ:
  580. case TAS_WRITE_EQ:
  581. return tas3001c_eq_rw(self, cmd, arg);
  582. case TAS_READ_EQ_LIST:
  583. case TAS_WRITE_EQ_LIST:
  584. return tas3001c_eq_list_rw(self, cmd, arg);
  585. case TAS_READ_EQ_FILTER_COUNT:
  586. put_user(TAS3001C_BIQUAD_FILTER_COUNT, argp);
  587. return 0;
  588. case TAS_READ_EQ_CHANNEL_COUNT:
  589. put_user(TAS3001C_BIQUAD_CHANNEL_COUNT, argp);
  590. return 0;
  591. case TAS_READ_DRCE:
  592. case TAS_WRITE_DRCE:
  593. return tas3001c_drce_rw(self, cmd, arg);
  594. case TAS_READ_DRCE_CAPS:
  595. put_user(TAS_DRCE_ENABLE | TAS_DRCE_THRESHOLD, argp);
  596. return 0;
  597. case TAS_READ_DRCE_MIN:
  598. case TAS_READ_DRCE_MAX: {
  599. struct tas_drce_ctrl_t drce_ctrl;
  600. if (copy_from_user(&drce_ctrl, argp,
  601. sizeof(struct tas_drce_ctrl_t))) {
  602. return -EFAULT;
  603. }
  604. if (drce_ctrl.flags & TAS_DRCE_THRESHOLD) {
  605. if (cmd == TAS_READ_DRCE_MIN) {
  606. drce_ctrl.data.threshold=-36<<8;
  607. } else {
  608. drce_ctrl.data.threshold=-6<<8;
  609. }
  610. }
  611. if (copy_to_user(argp, &drce_ctrl,
  612. sizeof(struct tas_drce_ctrl_t))) {
  613. return -EFAULT;
  614. }
  615. }
  616. }
  617. return -EINVAL;
  618. }
  619. static int
  620. tas3001c_init_mixer(struct tas3001c_data_t *self)
  621. {
  622. unsigned char mcr = (1<<6)+(2<<4)+(2<<2);
  623. /* Make sure something answers on the i2c bus */
  624. if (tas3001c_write_register(self, TAS3001C_REG_MCR, &mcr,
  625. WRITE_NORMAL|FORCE_WRITE) < 0)
  626. return -1;
  627. tas3001c_fast_load(self, 1);
  628. (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD0);
  629. (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD1);
  630. (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD2);
  631. (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD3);
  632. (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD4);
  633. (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD5);
  634. (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD6);
  635. (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD0);
  636. (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD1);
  637. (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD2);
  638. (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD3);
  639. (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD4);
  640. (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD5);
  641. (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD6);
  642. tas3001c_fast_load(self, 0);
  643. tas3001c_set_mixer_level(self, SOUND_MIXER_VOLUME, VOL_DEFAULT<<8 | VOL_DEFAULT);
  644. tas3001c_set_mixer_level(self, SOUND_MIXER_PCM, INPUT_DEFAULT<<8 | INPUT_DEFAULT);
  645. tas3001c_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0);
  646. tas3001c_set_mixer_level(self, SOUND_MIXER_BASS, BASS_DEFAULT);
  647. tas3001c_set_mixer_level(self, SOUND_MIXER_TREBLE, TREBLE_DEFAULT);
  648. return 0;
  649. }
  650. static int
  651. tas3001c_uninit_mixer(struct tas3001c_data_t *self)
  652. {
  653. tas3001c_set_mixer_level(self, SOUND_MIXER_VOLUME, 0);
  654. tas3001c_set_mixer_level(self, SOUND_MIXER_PCM, 0);
  655. tas3001c_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0);
  656. tas3001c_set_mixer_level(self, SOUND_MIXER_BASS, 0);
  657. tas3001c_set_mixer_level(self, SOUND_MIXER_TREBLE, 0);
  658. return 0;
  659. }
  660. static int
  661. tas3001c_init(struct i2c_client *client)
  662. {
  663. struct tas3001c_data_t *self;
  664. size_t sz = sizeof(*self) + (TAS3001C_REG_MAX*sizeof(tas_shadow_t));
  665. int i, j;
  666. self = kmalloc(sz, GFP_KERNEL);
  667. if (!self)
  668. return -ENOMEM;
  669. memset(self, 0, sz);
  670. self->super.client = client;
  671. self->super.shadow = (tas_shadow_t *)(self+1);
  672. self->output_id = TAS_OUTPUT_HEADPHONES;
  673. dev_set_drvdata(&client->dev, self);
  674. for (i = 0; i < TAS3001C_BIQUAD_CHANNEL_COUNT; i++)
  675. for (j = 0; j < TAS3001C_BIQUAD_FILTER_COUNT; j++)
  676. tas3001c_write_biquad_shadow(self, i, j,
  677. &tas3001c_eq_unity);
  678. INIT_WORK(&device_change, tas3001c_device_change_handler, self);
  679. return 0;
  680. }
  681. static void
  682. tas3001c_uninit(struct tas3001c_data_t *self)
  683. {
  684. tas3001c_uninit_mixer(self);
  685. kfree(self);
  686. }
  687. struct tas_driver_hooks_t tas3001c_hooks = {
  688. .init = (tas_hook_init_t)tas3001c_init,
  689. .post_init = (tas_hook_post_init_t)tas3001c_init_mixer,
  690. .uninit = (tas_hook_uninit_t)tas3001c_uninit,
  691. .get_mixer_level = (tas_hook_get_mixer_level_t)tas3001c_get_mixer_level,
  692. .set_mixer_level = (tas_hook_set_mixer_level_t)tas3001c_set_mixer_level,
  693. .enter_sleep = (tas_hook_enter_sleep_t)tas3001c_enter_sleep,
  694. .leave_sleep = (tas_hook_leave_sleep_t)tas3001c_leave_sleep,
  695. .supported_mixers = (tas_hook_supported_mixers_t)tas3001c_supported_mixers,
  696. .mixer_is_stereo = (tas_hook_mixer_is_stereo_t)tas3001c_mixer_is_stereo,
  697. .stereo_mixers = (tas_hook_stereo_mixers_t)tas3001c_stereo_mixers,
  698. .output_device_change = (tas_hook_output_device_change_t)tas3001c_output_device_change,
  699. .device_ioctl = (tas_hook_device_ioctl_t)tas3001c_device_ioctl
  700. };