tas3004.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140
  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. * Input support by Renzo Davoli <renzo@cs.unibo.it>
  9. *
  10. */
  11. #include <linux/module.h>
  12. #include <linux/slab.h>
  13. #include <linux/proc_fs.h>
  14. #include <linux/ioport.h>
  15. #include <linux/sysctl.h>
  16. #include <linux/types.h>
  17. #include <linux/i2c.h>
  18. #include <linux/init.h>
  19. #include <linux/soundcard.h>
  20. #include <linux/interrupt.h>
  21. #include <linux/workqueue.h>
  22. #include <asm/uaccess.h>
  23. #include <asm/errno.h>
  24. #include <asm/io.h>
  25. #include <asm/prom.h>
  26. #include "dmasound.h"
  27. #include "tas_common.h"
  28. #include "tas3004.h"
  29. #include "tas_ioctl.h"
  30. /* #define DEBUG_DRCE */
  31. #define TAS3004_BIQUAD_FILTER_COUNT 7
  32. #define TAS3004_BIQUAD_CHANNEL_COUNT 2
  33. #define VOL_DEFAULT (100 * 4 / 5)
  34. #define INPUT_DEFAULT (100 * 4 / 5)
  35. #define BASS_DEFAULT (100 / 2)
  36. #define TREBLE_DEFAULT (100 / 2)
  37. struct tas3004_data_t {
  38. struct tas_data_t super;
  39. int device_id;
  40. int output_id;
  41. int speaker_id;
  42. struct tas_drce_t drce_state;
  43. };
  44. #define MAKE_TIME(sec,usec) (((sec)<<12) + (50000+(usec/10)*(1<<12))/100000)
  45. #define MAKE_RATIO(i,f) (((i)<<8) + ((500+(f)*(1<<8))/1000))
  46. static const union tas_biquad_t tas3004_eq_unity = {
  47. .buf = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 },
  48. };
  49. static const struct tas_drce_t tas3004_drce_min = {
  50. .enable = 1,
  51. .above = { .val = MAKE_RATIO(16,0), .expand = 0 },
  52. .below = { .val = MAKE_RATIO(2,0), .expand = 0 },
  53. .threshold = -0x59a0,
  54. .energy = MAKE_TIME(0, 1700),
  55. .attack = MAKE_TIME(0, 1700),
  56. .decay = MAKE_TIME(0, 1700),
  57. };
  58. static const struct tas_drce_t tas3004_drce_max = {
  59. .enable = 1,
  60. .above = { .val = MAKE_RATIO(1,500), .expand = 1 },
  61. .below = { .val = MAKE_RATIO(2,0), .expand = 1 },
  62. .threshold = -0x0,
  63. .energy = MAKE_TIME(2,400000),
  64. .attack = MAKE_TIME(2,400000),
  65. .decay = MAKE_TIME(2,400000),
  66. };
  67. static const unsigned short time_constants[]={
  68. MAKE_TIME(0, 1700),
  69. MAKE_TIME(0, 3500),
  70. MAKE_TIME(0, 6700),
  71. MAKE_TIME(0, 13000),
  72. MAKE_TIME(0, 26000),
  73. MAKE_TIME(0, 53000),
  74. MAKE_TIME(0,106000),
  75. MAKE_TIME(0,212000),
  76. MAKE_TIME(0,425000),
  77. MAKE_TIME(0,850000),
  78. MAKE_TIME(1,700000),
  79. MAKE_TIME(2,400000),
  80. };
  81. static const unsigned short above_threshold_compression_ratio[]={
  82. MAKE_RATIO( 1, 70),
  83. MAKE_RATIO( 1,140),
  84. MAKE_RATIO( 1,230),
  85. MAKE_RATIO( 1,330),
  86. MAKE_RATIO( 1,450),
  87. MAKE_RATIO( 1,600),
  88. MAKE_RATIO( 1,780),
  89. MAKE_RATIO( 2, 0),
  90. MAKE_RATIO( 2,290),
  91. MAKE_RATIO( 2,670),
  92. MAKE_RATIO( 3,200),
  93. MAKE_RATIO( 4, 0),
  94. MAKE_RATIO( 5,330),
  95. MAKE_RATIO( 8, 0),
  96. MAKE_RATIO(16, 0),
  97. };
  98. static const unsigned short above_threshold_expansion_ratio[]={
  99. MAKE_RATIO(1, 60),
  100. MAKE_RATIO(1,130),
  101. MAKE_RATIO(1,190),
  102. MAKE_RATIO(1,250),
  103. MAKE_RATIO(1,310),
  104. MAKE_RATIO(1,380),
  105. MAKE_RATIO(1,440),
  106. MAKE_RATIO(1,500)
  107. };
  108. static const unsigned short below_threshold_compression_ratio[]={
  109. MAKE_RATIO(1, 70),
  110. MAKE_RATIO(1,140),
  111. MAKE_RATIO(1,230),
  112. MAKE_RATIO(1,330),
  113. MAKE_RATIO(1,450),
  114. MAKE_RATIO(1,600),
  115. MAKE_RATIO(1,780),
  116. MAKE_RATIO(2, 0)
  117. };
  118. static const unsigned short below_threshold_expansion_ratio[]={
  119. MAKE_RATIO(1, 60),
  120. MAKE_RATIO(1,130),
  121. MAKE_RATIO(1,190),
  122. MAKE_RATIO(1,250),
  123. MAKE_RATIO(1,310),
  124. MAKE_RATIO(1,380),
  125. MAKE_RATIO(1,440),
  126. MAKE_RATIO(1,500),
  127. MAKE_RATIO(1,560),
  128. MAKE_RATIO(1,630),
  129. MAKE_RATIO(1,690),
  130. MAKE_RATIO(1,750),
  131. MAKE_RATIO(1,810),
  132. MAKE_RATIO(1,880),
  133. MAKE_RATIO(1,940),
  134. MAKE_RATIO(2, 0)
  135. };
  136. static inline int
  137. search( unsigned short val,
  138. const unsigned short *arr,
  139. const int arrsize) {
  140. /*
  141. * This could be a binary search, but for small tables,
  142. * a linear search is likely to be faster
  143. */
  144. int i;
  145. for (i=0; i < arrsize; i++)
  146. if (arr[i] >= val)
  147. goto _1;
  148. return arrsize-1;
  149. _1:
  150. if (i == 0)
  151. return 0;
  152. return (arr[i]-val < val-arr[i-1]) ? i : i-1;
  153. }
  154. #define SEARCH(a, b) search(a, b, ARRAY_SIZE(b))
  155. static inline int
  156. time_index(unsigned short time)
  157. {
  158. return SEARCH(time, time_constants);
  159. }
  160. static inline int
  161. above_threshold_compression_index(unsigned short ratio)
  162. {
  163. return SEARCH(ratio, above_threshold_compression_ratio);
  164. }
  165. static inline int
  166. above_threshold_expansion_index(unsigned short ratio)
  167. {
  168. return SEARCH(ratio, above_threshold_expansion_ratio);
  169. }
  170. static inline int
  171. below_threshold_compression_index(unsigned short ratio)
  172. {
  173. return SEARCH(ratio, below_threshold_compression_ratio);
  174. }
  175. static inline int
  176. below_threshold_expansion_index(unsigned short ratio)
  177. {
  178. return SEARCH(ratio, below_threshold_expansion_ratio);
  179. }
  180. static inline unsigned char db_to_regval(short db) {
  181. int r=0;
  182. r=(db+0x59a0) / 0x60;
  183. if (r < 0x91) return 0x91;
  184. if (r > 0xef) return 0xef;
  185. return r;
  186. }
  187. static inline short quantize_db(short db)
  188. {
  189. return db_to_regval(db) * 0x60 - 0x59a0;
  190. }
  191. static inline int
  192. register_width(enum tas3004_reg_t r)
  193. {
  194. switch(r) {
  195. case TAS3004_REG_MCR:
  196. case TAS3004_REG_TREBLE:
  197. case TAS3004_REG_BASS:
  198. case TAS3004_REG_ANALOG_CTRL:
  199. case TAS3004_REG_TEST1:
  200. case TAS3004_REG_TEST2:
  201. case TAS3004_REG_MCR2:
  202. return 1;
  203. case TAS3004_REG_LEFT_LOUD_BIQUAD_GAIN:
  204. case TAS3004_REG_RIGHT_LOUD_BIQUAD_GAIN:
  205. return 3;
  206. case TAS3004_REG_DRC:
  207. case TAS3004_REG_VOLUME:
  208. return 6;
  209. case TAS3004_REG_LEFT_MIXER:
  210. case TAS3004_REG_RIGHT_MIXER:
  211. return 9;
  212. case TAS3004_REG_TEST:
  213. return 10;
  214. case TAS3004_REG_LEFT_BIQUAD0:
  215. case TAS3004_REG_LEFT_BIQUAD1:
  216. case TAS3004_REG_LEFT_BIQUAD2:
  217. case TAS3004_REG_LEFT_BIQUAD3:
  218. case TAS3004_REG_LEFT_BIQUAD4:
  219. case TAS3004_REG_LEFT_BIQUAD5:
  220. case TAS3004_REG_LEFT_BIQUAD6:
  221. case TAS3004_REG_RIGHT_BIQUAD0:
  222. case TAS3004_REG_RIGHT_BIQUAD1:
  223. case TAS3004_REG_RIGHT_BIQUAD2:
  224. case TAS3004_REG_RIGHT_BIQUAD3:
  225. case TAS3004_REG_RIGHT_BIQUAD4:
  226. case TAS3004_REG_RIGHT_BIQUAD5:
  227. case TAS3004_REG_RIGHT_BIQUAD6:
  228. case TAS3004_REG_LEFT_LOUD_BIQUAD:
  229. case TAS3004_REG_RIGHT_LOUD_BIQUAD:
  230. return 15;
  231. default:
  232. return 0;
  233. }
  234. }
  235. static int
  236. tas3004_write_register( struct tas3004_data_t *self,
  237. enum tas3004_reg_t reg_num,
  238. char *data,
  239. uint write_mode)
  240. {
  241. if (reg_num==TAS3004_REG_MCR ||
  242. reg_num==TAS3004_REG_BASS ||
  243. reg_num==TAS3004_REG_TREBLE ||
  244. reg_num==TAS3004_REG_ANALOG_CTRL) {
  245. return tas_write_byte_register(&self->super,
  246. (uint)reg_num,
  247. *data,
  248. write_mode);
  249. } else {
  250. return tas_write_register(&self->super,
  251. (uint)reg_num,
  252. register_width(reg_num),
  253. data,
  254. write_mode);
  255. }
  256. }
  257. static int
  258. tas3004_sync_register( struct tas3004_data_t *self,
  259. enum tas3004_reg_t reg_num)
  260. {
  261. if (reg_num==TAS3004_REG_MCR ||
  262. reg_num==TAS3004_REG_BASS ||
  263. reg_num==TAS3004_REG_TREBLE ||
  264. reg_num==TAS3004_REG_ANALOG_CTRL) {
  265. return tas_sync_byte_register(&self->super,
  266. (uint)reg_num,
  267. register_width(reg_num));
  268. } else {
  269. return tas_sync_register(&self->super,
  270. (uint)reg_num,
  271. register_width(reg_num));
  272. }
  273. }
  274. static int
  275. tas3004_read_register( struct tas3004_data_t *self,
  276. enum tas3004_reg_t reg_num,
  277. char *data,
  278. uint write_mode)
  279. {
  280. return tas_read_register(&self->super,
  281. (uint)reg_num,
  282. register_width(reg_num),
  283. data);
  284. }
  285. static inline int
  286. tas3004_fast_load(struct tas3004_data_t *self, int fast)
  287. {
  288. if (fast)
  289. self->super.shadow[TAS3004_REG_MCR][0] |= 0x80;
  290. else
  291. self->super.shadow[TAS3004_REG_MCR][0] &= 0x7f;
  292. return tas3004_sync_register(self,TAS3004_REG_MCR);
  293. }
  294. static uint
  295. tas3004_supported_mixers(struct tas3004_data_t *self)
  296. {
  297. return SOUND_MASK_VOLUME |
  298. SOUND_MASK_PCM |
  299. SOUND_MASK_ALTPCM |
  300. SOUND_MASK_IMIX |
  301. SOUND_MASK_TREBLE |
  302. SOUND_MASK_BASS |
  303. SOUND_MASK_MIC |
  304. SOUND_MASK_LINE;
  305. }
  306. static int
  307. tas3004_mixer_is_stereo(struct tas3004_data_t *self, int mixer)
  308. {
  309. switch(mixer) {
  310. case SOUND_MIXER_VOLUME:
  311. case SOUND_MIXER_PCM:
  312. case SOUND_MIXER_ALTPCM:
  313. case SOUND_MIXER_IMIX:
  314. return 1;
  315. default:
  316. return 0;
  317. }
  318. }
  319. static uint
  320. tas3004_stereo_mixers(struct tas3004_data_t *self)
  321. {
  322. uint r = tas3004_supported_mixers(self);
  323. uint i;
  324. for (i=1; i<SOUND_MIXER_NRDEVICES; i++)
  325. if (r&(1<<i) && !tas3004_mixer_is_stereo(self,i))
  326. r &= ~(1<<i);
  327. return r;
  328. }
  329. static int
  330. tas3004_get_mixer_level(struct tas3004_data_t *self, int mixer, uint *level)
  331. {
  332. if (!self)
  333. return -1;
  334. *level = self->super.mixer[mixer];
  335. return 0;
  336. }
  337. static int
  338. tas3004_set_mixer_level(struct tas3004_data_t *self, int mixer, uint level)
  339. {
  340. int rc;
  341. tas_shadow_t *shadow;
  342. uint temp;
  343. uint offset=0;
  344. if (!self)
  345. return -1;
  346. shadow = self->super.shadow;
  347. if (!tas3004_mixer_is_stereo(self,mixer))
  348. level = tas_mono_to_stereo(level);
  349. switch(mixer) {
  350. case SOUND_MIXER_VOLUME:
  351. temp = tas3004_gain.master[level&0xff];
  352. SET_4_20(shadow[TAS3004_REG_VOLUME], 0, temp);
  353. temp = tas3004_gain.master[(level>>8)&0xff];
  354. SET_4_20(shadow[TAS3004_REG_VOLUME], 3, temp);
  355. rc = tas3004_sync_register(self,TAS3004_REG_VOLUME);
  356. break;
  357. case SOUND_MIXER_IMIX:
  358. offset += 3;
  359. case SOUND_MIXER_ALTPCM:
  360. offset += 3;
  361. case SOUND_MIXER_PCM:
  362. /*
  363. * Don't load these in fast mode. The documentation
  364. * says it can be done in either mode, but testing it
  365. * shows that fast mode produces ugly clicking.
  366. */
  367. /* tas3004_fast_load(self,1); */
  368. temp = tas3004_gain.mixer[level&0xff];
  369. SET_4_20(shadow[TAS3004_REG_LEFT_MIXER], offset, temp);
  370. temp = tas3004_gain.mixer[(level>>8)&0xff];
  371. SET_4_20(shadow[TAS3004_REG_RIGHT_MIXER], offset, temp);
  372. rc = tas3004_sync_register(self,TAS3004_REG_LEFT_MIXER);
  373. if (rc == 0)
  374. rc=tas3004_sync_register(self,TAS3004_REG_RIGHT_MIXER);
  375. /* tas3004_fast_load(self,0); */
  376. break;
  377. case SOUND_MIXER_TREBLE:
  378. temp = tas3004_gain.treble[level&0xff];
  379. shadow[TAS3004_REG_TREBLE][0]=temp&0xff;
  380. rc = tas3004_sync_register(self,TAS3004_REG_TREBLE);
  381. break;
  382. case SOUND_MIXER_BASS:
  383. temp = tas3004_gain.bass[level&0xff];
  384. shadow[TAS3004_REG_BASS][0]=temp&0xff;
  385. rc = tas3004_sync_register(self,TAS3004_REG_BASS);
  386. break;
  387. case SOUND_MIXER_MIC:
  388. if ((level&0xff)>0) {
  389. software_input_volume = SW_INPUT_VOLUME_SCALE * (level&0xff);
  390. if (self->super.mixer[mixer] == 0) {
  391. self->super.mixer[SOUND_MIXER_LINE] = 0;
  392. shadow[TAS3004_REG_ANALOG_CTRL][0]=0xc2;
  393. rc = tas3004_sync_register(self,TAS3004_REG_ANALOG_CTRL);
  394. } else rc=0;
  395. } else {
  396. self->super.mixer[SOUND_MIXER_LINE] = SW_INPUT_VOLUME_DEFAULT;
  397. software_input_volume = SW_INPUT_VOLUME_SCALE *
  398. (self->super.mixer[SOUND_MIXER_LINE]&0xff);
  399. shadow[TAS3004_REG_ANALOG_CTRL][0]=0x00;
  400. rc = tas3004_sync_register(self,TAS3004_REG_ANALOG_CTRL);
  401. }
  402. break;
  403. case SOUND_MIXER_LINE:
  404. if (self->super.mixer[SOUND_MIXER_MIC] == 0) {
  405. software_input_volume = SW_INPUT_VOLUME_SCALE * (level&0xff);
  406. rc=0;
  407. }
  408. break;
  409. default:
  410. rc = -1;
  411. break;
  412. }
  413. if (rc < 0)
  414. return rc;
  415. self->super.mixer[mixer] = level;
  416. return 0;
  417. }
  418. static int
  419. tas3004_leave_sleep(struct tas3004_data_t *self)
  420. {
  421. unsigned char mcr = (1<<6)+(2<<4)+(2<<2);
  422. if (!self)
  423. return -1;
  424. /* Make sure something answers on the i2c bus */
  425. if (tas3004_write_register(self, TAS3004_REG_MCR, &mcr,
  426. WRITE_NORMAL | FORCE_WRITE) < 0)
  427. return -1;
  428. tas3004_fast_load(self, 1);
  429. (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD0);
  430. (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD1);
  431. (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD2);
  432. (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD3);
  433. (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD4);
  434. (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD5);
  435. (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD6);
  436. (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD0);
  437. (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD1);
  438. (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD2);
  439. (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD3);
  440. (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD4);
  441. (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD5);
  442. (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD6);
  443. tas3004_fast_load(self, 0);
  444. (void)tas3004_sync_register(self,TAS3004_REG_VOLUME);
  445. (void)tas3004_sync_register(self,TAS3004_REG_LEFT_MIXER);
  446. (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_MIXER);
  447. (void)tas3004_sync_register(self,TAS3004_REG_TREBLE);
  448. (void)tas3004_sync_register(self,TAS3004_REG_BASS);
  449. (void)tas3004_sync_register(self,TAS3004_REG_ANALOG_CTRL);
  450. return 0;
  451. }
  452. static int
  453. tas3004_enter_sleep(struct tas3004_data_t *self)
  454. {
  455. if (!self)
  456. return -1;
  457. return 0;
  458. }
  459. static int
  460. tas3004_sync_biquad( struct tas3004_data_t *self,
  461. u_int channel,
  462. u_int filter)
  463. {
  464. enum tas3004_reg_t reg;
  465. if (channel >= TAS3004_BIQUAD_CHANNEL_COUNT ||
  466. filter >= TAS3004_BIQUAD_FILTER_COUNT) return -EINVAL;
  467. reg=( channel ? TAS3004_REG_RIGHT_BIQUAD0 : TAS3004_REG_LEFT_BIQUAD0 ) + filter;
  468. return tas3004_sync_register(self,reg);
  469. }
  470. static int
  471. tas3004_write_biquad_shadow( struct tas3004_data_t *self,
  472. u_int channel,
  473. u_int filter,
  474. const union tas_biquad_t *biquad)
  475. {
  476. tas_shadow_t *shadow=self->super.shadow;
  477. enum tas3004_reg_t reg;
  478. if (channel >= TAS3004_BIQUAD_CHANNEL_COUNT ||
  479. filter >= TAS3004_BIQUAD_FILTER_COUNT) return -EINVAL;
  480. reg=( channel ? TAS3004_REG_RIGHT_BIQUAD0 : TAS3004_REG_LEFT_BIQUAD0 ) + filter;
  481. SET_4_20(shadow[reg], 0,biquad->coeff.b0);
  482. SET_4_20(shadow[reg], 3,biquad->coeff.b1);
  483. SET_4_20(shadow[reg], 6,biquad->coeff.b2);
  484. SET_4_20(shadow[reg], 9,biquad->coeff.a1);
  485. SET_4_20(shadow[reg],12,biquad->coeff.a2);
  486. return 0;
  487. }
  488. static int
  489. tas3004_write_biquad( struct tas3004_data_t *self,
  490. u_int channel,
  491. u_int filter,
  492. const union tas_biquad_t *biquad)
  493. {
  494. int rc;
  495. rc=tas3004_write_biquad_shadow(self, channel, filter, biquad);
  496. if (rc < 0) return rc;
  497. return tas3004_sync_biquad(self, channel, filter);
  498. }
  499. static int
  500. tas3004_write_biquad_list( struct tas3004_data_t *self,
  501. u_int filter_count,
  502. u_int flags,
  503. struct tas_biquad_ctrl_t *biquads)
  504. {
  505. int i;
  506. int rc;
  507. if (flags & TAS_BIQUAD_FAST_LOAD) tas3004_fast_load(self,1);
  508. for (i=0; i<filter_count; i++) {
  509. rc=tas3004_write_biquad(self,
  510. biquads[i].channel,
  511. biquads[i].filter,
  512. &biquads[i].data);
  513. if (rc < 0) break;
  514. }
  515. if (flags & TAS_BIQUAD_FAST_LOAD) tas3004_fast_load(self,0);
  516. return rc;
  517. }
  518. static int
  519. tas3004_read_biquad( struct tas3004_data_t *self,
  520. u_int channel,
  521. u_int filter,
  522. union tas_biquad_t *biquad)
  523. {
  524. tas_shadow_t *shadow=self->super.shadow;
  525. enum tas3004_reg_t reg;
  526. if (channel >= TAS3004_BIQUAD_CHANNEL_COUNT ||
  527. filter >= TAS3004_BIQUAD_FILTER_COUNT) return -EINVAL;
  528. reg=( channel ? TAS3004_REG_RIGHT_BIQUAD0 : TAS3004_REG_LEFT_BIQUAD0 ) + filter;
  529. biquad->coeff.b0=GET_4_20(shadow[reg], 0);
  530. biquad->coeff.b1=GET_4_20(shadow[reg], 3);
  531. biquad->coeff.b2=GET_4_20(shadow[reg], 6);
  532. biquad->coeff.a1=GET_4_20(shadow[reg], 9);
  533. biquad->coeff.a2=GET_4_20(shadow[reg],12);
  534. return 0;
  535. }
  536. static int
  537. tas3004_eq_rw( struct tas3004_data_t *self,
  538. u_int cmd,
  539. u_long arg)
  540. {
  541. void __user *argp = (void __user *)arg;
  542. int rc;
  543. struct tas_biquad_ctrl_t biquad;
  544. if (copy_from_user((void *)&biquad, argp, sizeof(struct tas_biquad_ctrl_t))) {
  545. return -EFAULT;
  546. }
  547. if (cmd & SIOC_IN) {
  548. rc=tas3004_write_biquad(self, biquad.channel, biquad.filter, &biquad.data);
  549. if (rc != 0) return rc;
  550. }
  551. if (cmd & SIOC_OUT) {
  552. rc=tas3004_read_biquad(self, biquad.channel, biquad.filter, &biquad.data);
  553. if (rc != 0) return rc;
  554. if (copy_to_user(argp, &biquad, sizeof(struct tas_biquad_ctrl_t))) {
  555. return -EFAULT;
  556. }
  557. }
  558. return 0;
  559. }
  560. static int
  561. tas3004_eq_list_rw( struct tas3004_data_t *self,
  562. u_int cmd,
  563. u_long arg)
  564. {
  565. int rc = 0;
  566. int filter_count;
  567. int flags;
  568. int i,j;
  569. char sync_required[TAS3004_BIQUAD_CHANNEL_COUNT][TAS3004_BIQUAD_FILTER_COUNT];
  570. struct tas_biquad_ctrl_t biquad;
  571. struct tas_biquad_ctrl_list_t __user *argp = (void __user *)arg;
  572. memset(sync_required,0,sizeof(sync_required));
  573. if (copy_from_user(&filter_count, &argp->filter_count, sizeof(int)))
  574. return -EFAULT;
  575. if (copy_from_user(&flags, &argp->flags, sizeof(int)))
  576. return -EFAULT;
  577. if (cmd & SIOC_IN) {
  578. }
  579. for (i=0; i < filter_count; i++) {
  580. if (copy_from_user(&biquad, &argp->biquads[i],
  581. sizeof(struct tas_biquad_ctrl_t))) {
  582. return -EFAULT;
  583. }
  584. if (cmd & SIOC_IN) {
  585. sync_required[biquad.channel][biquad.filter]=1;
  586. rc=tas3004_write_biquad_shadow(self, biquad.channel, biquad.filter, &biquad.data);
  587. if (rc != 0) return rc;
  588. }
  589. if (cmd & SIOC_OUT) {
  590. rc=tas3004_read_biquad(self, biquad.channel, biquad.filter, &biquad.data);
  591. if (rc != 0) return rc;
  592. if (copy_to_user(&argp->biquads[i], &biquad,
  593. sizeof(struct tas_biquad_ctrl_t))) {
  594. return -EFAULT;
  595. }
  596. }
  597. }
  598. if (cmd & SIOC_IN) {
  599. /*
  600. * This is OK for the tas3004. For the
  601. * tas3001c, going into fast load mode causes
  602. * the treble and bass to be reset to 0dB, and
  603. * volume controls to be muted.
  604. */
  605. if (flags & TAS_BIQUAD_FAST_LOAD) tas3004_fast_load(self,1);
  606. for (i=0; i<TAS3004_BIQUAD_CHANNEL_COUNT; i++) {
  607. for (j=0; j<TAS3004_BIQUAD_FILTER_COUNT; j++) {
  608. if (sync_required[i][j]) {
  609. rc=tas3004_sync_biquad(self, i, j);
  610. if (rc < 0) goto out;
  611. }
  612. }
  613. }
  614. out:
  615. if (flags & TAS_BIQUAD_FAST_LOAD)
  616. tas3004_fast_load(self,0);
  617. }
  618. return rc;
  619. }
  620. static int
  621. tas3004_update_drce( struct tas3004_data_t *self,
  622. int flags,
  623. struct tas_drce_t *drce)
  624. {
  625. tas_shadow_t *shadow;
  626. int i;
  627. shadow=self->super.shadow;
  628. if (flags & TAS_DRCE_ABOVE_RATIO) {
  629. self->drce_state.above.expand = drce->above.expand;
  630. if (drce->above.val == (1<<8)) {
  631. self->drce_state.above.val = 1<<8;
  632. shadow[TAS3004_REG_DRC][0] = 0x02;
  633. } else if (drce->above.expand) {
  634. i=above_threshold_expansion_index(drce->above.val);
  635. self->drce_state.above.val=above_threshold_expansion_ratio[i];
  636. shadow[TAS3004_REG_DRC][0] = 0x0a + (i<<3);
  637. } else {
  638. i=above_threshold_compression_index(drce->above.val);
  639. self->drce_state.above.val=above_threshold_compression_ratio[i];
  640. shadow[TAS3004_REG_DRC][0] = 0x08 + (i<<3);
  641. }
  642. }
  643. if (flags & TAS_DRCE_BELOW_RATIO) {
  644. self->drce_state.below.expand = drce->below.expand;
  645. if (drce->below.val == (1<<8)) {
  646. self->drce_state.below.val = 1<<8;
  647. shadow[TAS3004_REG_DRC][1] = 0x02;
  648. } else if (drce->below.expand) {
  649. i=below_threshold_expansion_index(drce->below.val);
  650. self->drce_state.below.val=below_threshold_expansion_ratio[i];
  651. shadow[TAS3004_REG_DRC][1] = 0x08 + (i<<3);
  652. } else {
  653. i=below_threshold_compression_index(drce->below.val);
  654. self->drce_state.below.val=below_threshold_compression_ratio[i];
  655. shadow[TAS3004_REG_DRC][1] = 0x0a + (i<<3);
  656. }
  657. }
  658. if (flags & TAS_DRCE_THRESHOLD) {
  659. self->drce_state.threshold=quantize_db(drce->threshold);
  660. shadow[TAS3004_REG_DRC][2] = db_to_regval(self->drce_state.threshold);
  661. }
  662. if (flags & TAS_DRCE_ENERGY) {
  663. i=time_index(drce->energy);
  664. self->drce_state.energy=time_constants[i];
  665. shadow[TAS3004_REG_DRC][3] = 0x40 + (i<<4);
  666. }
  667. if (flags & TAS_DRCE_ATTACK) {
  668. i=time_index(drce->attack);
  669. self->drce_state.attack=time_constants[i];
  670. shadow[TAS3004_REG_DRC][4] = 0x40 + (i<<4);
  671. }
  672. if (flags & TAS_DRCE_DECAY) {
  673. i=time_index(drce->decay);
  674. self->drce_state.decay=time_constants[i];
  675. shadow[TAS3004_REG_DRC][5] = 0x40 + (i<<4);
  676. }
  677. if (flags & TAS_DRCE_ENABLE) {
  678. self->drce_state.enable = drce->enable;
  679. }
  680. if (!self->drce_state.enable) {
  681. shadow[TAS3004_REG_DRC][0] |= 0x01;
  682. }
  683. #ifdef DEBUG_DRCE
  684. printk("DRCE: set [ ENABLE:%x ABOVE:%x/%x BELOW:%x/%x THRESH:%x ENERGY:%x ATTACK:%x DECAY:%x\n",
  685. self->drce_state.enable,
  686. self->drce_state.above.expand,self->drce_state.above.val,
  687. self->drce_state.below.expand,self->drce_state.below.val,
  688. self->drce_state.threshold,
  689. self->drce_state.energy,
  690. self->drce_state.attack,
  691. self->drce_state.decay);
  692. printk("DRCE: reg [ %02x %02x %02x %02x %02x %02x ]\n",
  693. (unsigned char)shadow[TAS3004_REG_DRC][0],
  694. (unsigned char)shadow[TAS3004_REG_DRC][1],
  695. (unsigned char)shadow[TAS3004_REG_DRC][2],
  696. (unsigned char)shadow[TAS3004_REG_DRC][3],
  697. (unsigned char)shadow[TAS3004_REG_DRC][4],
  698. (unsigned char)shadow[TAS3004_REG_DRC][5]);
  699. #endif
  700. return tas3004_sync_register(self, TAS3004_REG_DRC);
  701. }
  702. static int
  703. tas3004_drce_rw( struct tas3004_data_t *self,
  704. u_int cmd,
  705. u_long arg)
  706. {
  707. int rc;
  708. struct tas_drce_ctrl_t drce_ctrl;
  709. void __user *argp = (void __user *)arg;
  710. if (copy_from_user(&drce_ctrl, argp, sizeof(struct tas_drce_ctrl_t)))
  711. return -EFAULT;
  712. #ifdef DEBUG_DRCE
  713. printk("DRCE: input [ FLAGS:%x ENABLE:%x ABOVE:%x/%x BELOW:%x/%x THRESH:%x ENERGY:%x ATTACK:%x DECAY:%x\n",
  714. drce_ctrl.flags,
  715. drce_ctrl.data.enable,
  716. drce_ctrl.data.above.expand,drce_ctrl.data.above.val,
  717. drce_ctrl.data.below.expand,drce_ctrl.data.below.val,
  718. drce_ctrl.data.threshold,
  719. drce_ctrl.data.energy,
  720. drce_ctrl.data.attack,
  721. drce_ctrl.data.decay);
  722. #endif
  723. if (cmd & SIOC_IN) {
  724. rc = tas3004_update_drce(self, drce_ctrl.flags, &drce_ctrl.data);
  725. if (rc < 0) return rc;
  726. }
  727. if (cmd & SIOC_OUT) {
  728. if (drce_ctrl.flags & TAS_DRCE_ENABLE)
  729. drce_ctrl.data.enable = self->drce_state.enable;
  730. if (drce_ctrl.flags & TAS_DRCE_ABOVE_RATIO)
  731. drce_ctrl.data.above = self->drce_state.above;
  732. if (drce_ctrl.flags & TAS_DRCE_BELOW_RATIO)
  733. drce_ctrl.data.below = self->drce_state.below;
  734. if (drce_ctrl.flags & TAS_DRCE_THRESHOLD)
  735. drce_ctrl.data.threshold = self->drce_state.threshold;
  736. if (drce_ctrl.flags & TAS_DRCE_ENERGY)
  737. drce_ctrl.data.energy = self->drce_state.energy;
  738. if (drce_ctrl.flags & TAS_DRCE_ATTACK)
  739. drce_ctrl.data.attack = self->drce_state.attack;
  740. if (drce_ctrl.flags & TAS_DRCE_DECAY)
  741. drce_ctrl.data.decay = self->drce_state.decay;
  742. if (copy_to_user(argp, &drce_ctrl,
  743. sizeof(struct tas_drce_ctrl_t))) {
  744. return -EFAULT;
  745. }
  746. }
  747. return 0;
  748. }
  749. static void
  750. tas3004_update_device_parameters(struct tas3004_data_t *self)
  751. {
  752. char data;
  753. int i;
  754. if (!self) return;
  755. if (self->output_id == TAS_OUTPUT_HEADPHONES) {
  756. /* turn on allPass when headphones are plugged in */
  757. data = 0x02;
  758. } else {
  759. data = 0x00;
  760. }
  761. tas3004_write_register(self, TAS3004_REG_MCR2, &data, WRITE_NORMAL | FORCE_WRITE);
  762. for (i=0; tas3004_eq_prefs[i]; i++) {
  763. struct tas_eq_pref_t *eq = tas3004_eq_prefs[i];
  764. if (eq->device_id == self->device_id &&
  765. (eq->output_id == 0 || eq->output_id == self->output_id) &&
  766. (eq->speaker_id == 0 || eq->speaker_id == self->speaker_id)) {
  767. tas3004_update_drce(self, TAS_DRCE_ALL, eq->drce);
  768. tas3004_write_biquad_list(self, eq->filter_count, TAS_BIQUAD_FAST_LOAD, eq->biquads);
  769. break;
  770. }
  771. }
  772. }
  773. static void
  774. tas3004_device_change_handler(void *self)
  775. {
  776. if (!self) return;
  777. tas3004_update_device_parameters((struct tas3004_data_t *)self);
  778. }
  779. static struct work_struct device_change;
  780. static int
  781. tas3004_output_device_change( struct tas3004_data_t *self,
  782. int device_id,
  783. int output_id,
  784. int speaker_id)
  785. {
  786. self->device_id=device_id;
  787. self->output_id=output_id;
  788. self->speaker_id=speaker_id;
  789. schedule_work(&device_change);
  790. return 0;
  791. }
  792. static int
  793. tas3004_device_ioctl( struct tas3004_data_t *self,
  794. u_int cmd,
  795. u_long arg)
  796. {
  797. uint __user *argp = (void __user *)arg;
  798. switch (cmd) {
  799. case TAS_READ_EQ:
  800. case TAS_WRITE_EQ:
  801. return tas3004_eq_rw(self, cmd, arg);
  802. case TAS_READ_EQ_LIST:
  803. case TAS_WRITE_EQ_LIST:
  804. return tas3004_eq_list_rw(self, cmd, arg);
  805. case TAS_READ_EQ_FILTER_COUNT:
  806. put_user(TAS3004_BIQUAD_FILTER_COUNT, argp);
  807. return 0;
  808. case TAS_READ_EQ_CHANNEL_COUNT:
  809. put_user(TAS3004_BIQUAD_CHANNEL_COUNT, argp);
  810. return 0;
  811. case TAS_READ_DRCE:
  812. case TAS_WRITE_DRCE:
  813. return tas3004_drce_rw(self, cmd, arg);
  814. case TAS_READ_DRCE_CAPS:
  815. put_user(TAS_DRCE_ENABLE |
  816. TAS_DRCE_ABOVE_RATIO |
  817. TAS_DRCE_BELOW_RATIO |
  818. TAS_DRCE_THRESHOLD |
  819. TAS_DRCE_ENERGY |
  820. TAS_DRCE_ATTACK |
  821. TAS_DRCE_DECAY,
  822. argp);
  823. return 0;
  824. case TAS_READ_DRCE_MIN:
  825. case TAS_READ_DRCE_MAX: {
  826. struct tas_drce_ctrl_t drce_ctrl;
  827. const struct tas_drce_t *drce_copy;
  828. if (copy_from_user(&drce_ctrl, argp,
  829. sizeof(struct tas_drce_ctrl_t))) {
  830. return -EFAULT;
  831. }
  832. if (cmd == TAS_READ_DRCE_MIN) {
  833. drce_copy=&tas3004_drce_min;
  834. } else {
  835. drce_copy=&tas3004_drce_max;
  836. }
  837. if (drce_ctrl.flags & TAS_DRCE_ABOVE_RATIO) {
  838. drce_ctrl.data.above=drce_copy->above;
  839. }
  840. if (drce_ctrl.flags & TAS_DRCE_BELOW_RATIO) {
  841. drce_ctrl.data.below=drce_copy->below;
  842. }
  843. if (drce_ctrl.flags & TAS_DRCE_THRESHOLD) {
  844. drce_ctrl.data.threshold=drce_copy->threshold;
  845. }
  846. if (drce_ctrl.flags & TAS_DRCE_ENERGY) {
  847. drce_ctrl.data.energy=drce_copy->energy;
  848. }
  849. if (drce_ctrl.flags & TAS_DRCE_ATTACK) {
  850. drce_ctrl.data.attack=drce_copy->attack;
  851. }
  852. if (drce_ctrl.flags & TAS_DRCE_DECAY) {
  853. drce_ctrl.data.decay=drce_copy->decay;
  854. }
  855. if (copy_to_user(argp, &drce_ctrl,
  856. sizeof(struct tas_drce_ctrl_t))) {
  857. return -EFAULT;
  858. }
  859. }
  860. }
  861. return -EINVAL;
  862. }
  863. static int
  864. tas3004_init_mixer(struct tas3004_data_t *self)
  865. {
  866. unsigned char mcr = (1<<6)+(2<<4)+(2<<2);
  867. /* Make sure something answers on the i2c bus */
  868. if (tas3004_write_register(self, TAS3004_REG_MCR, &mcr,
  869. WRITE_NORMAL | FORCE_WRITE) < 0)
  870. return -1;
  871. tas3004_fast_load(self, 1);
  872. (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD0);
  873. (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD1);
  874. (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD2);
  875. (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD3);
  876. (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD4);
  877. (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD5);
  878. (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD6);
  879. (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD0);
  880. (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD1);
  881. (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD2);
  882. (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD3);
  883. (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD4);
  884. (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD5);
  885. (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD6);
  886. tas3004_sync_register(self, TAS3004_REG_DRC);
  887. tas3004_sync_register(self, TAS3004_REG_MCR2);
  888. tas3004_fast_load(self, 0);
  889. tas3004_set_mixer_level(self, SOUND_MIXER_VOLUME, VOL_DEFAULT<<8 | VOL_DEFAULT);
  890. tas3004_set_mixer_level(self, SOUND_MIXER_PCM, INPUT_DEFAULT<<8 | INPUT_DEFAULT);
  891. tas3004_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0);
  892. tas3004_set_mixer_level(self, SOUND_MIXER_IMIX, 0);
  893. tas3004_set_mixer_level(self, SOUND_MIXER_BASS, BASS_DEFAULT);
  894. tas3004_set_mixer_level(self, SOUND_MIXER_TREBLE, TREBLE_DEFAULT);
  895. tas3004_set_mixer_level(self, SOUND_MIXER_LINE,SW_INPUT_VOLUME_DEFAULT);
  896. return 0;
  897. }
  898. static int
  899. tas3004_uninit_mixer(struct tas3004_data_t *self)
  900. {
  901. tas3004_set_mixer_level(self, SOUND_MIXER_VOLUME, 0);
  902. tas3004_set_mixer_level(self, SOUND_MIXER_PCM, 0);
  903. tas3004_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0);
  904. tas3004_set_mixer_level(self, SOUND_MIXER_IMIX, 0);
  905. tas3004_set_mixer_level(self, SOUND_MIXER_BASS, 0);
  906. tas3004_set_mixer_level(self, SOUND_MIXER_TREBLE, 0);
  907. tas3004_set_mixer_level(self, SOUND_MIXER_LINE, 0);
  908. return 0;
  909. }
  910. static int
  911. tas3004_init(struct i2c_client *client)
  912. {
  913. struct tas3004_data_t *self;
  914. size_t sz = sizeof(*self) + (TAS3004_REG_MAX*sizeof(tas_shadow_t));
  915. char drce_init[] = { 0x69, 0x22, 0x9f, 0xb0, 0x60, 0xa0 };
  916. char mcr2 = 0;
  917. int i, j;
  918. self = kmalloc(sz, GFP_KERNEL);
  919. if (!self)
  920. return -ENOMEM;
  921. memset(self, 0, sz);
  922. self->super.client = client;
  923. self->super.shadow = (tas_shadow_t *)(self+1);
  924. self->output_id = TAS_OUTPUT_HEADPHONES;
  925. dev_set_drvdata(&client->dev, self);
  926. for (i = 0; i < TAS3004_BIQUAD_CHANNEL_COUNT; i++)
  927. for (j = 0; j<TAS3004_BIQUAD_FILTER_COUNT; j++)
  928. tas3004_write_biquad_shadow(self, i, j,
  929. &tas3004_eq_unity);
  930. tas3004_write_register(self, TAS3004_REG_MCR2, &mcr2, WRITE_SHADOW);
  931. tas3004_write_register(self, TAS3004_REG_DRC, drce_init, WRITE_SHADOW);
  932. INIT_WORK(&device_change, tas3004_device_change_handler, self);
  933. return 0;
  934. }
  935. static void
  936. tas3004_uninit(struct tas3004_data_t *self)
  937. {
  938. tas3004_uninit_mixer(self);
  939. kfree(self);
  940. }
  941. struct tas_driver_hooks_t tas3004_hooks = {
  942. .init = (tas_hook_init_t)tas3004_init,
  943. .post_init = (tas_hook_post_init_t)tas3004_init_mixer,
  944. .uninit = (tas_hook_uninit_t)tas3004_uninit,
  945. .get_mixer_level = (tas_hook_get_mixer_level_t)tas3004_get_mixer_level,
  946. .set_mixer_level = (tas_hook_set_mixer_level_t)tas3004_set_mixer_level,
  947. .enter_sleep = (tas_hook_enter_sleep_t)tas3004_enter_sleep,
  948. .leave_sleep = (tas_hook_leave_sleep_t)tas3004_leave_sleep,
  949. .supported_mixers = (tas_hook_supported_mixers_t)tas3004_supported_mixers,
  950. .mixer_is_stereo = (tas_hook_mixer_is_stereo_t)tas3004_mixer_is_stereo,
  951. .stereo_mixers = (tas_hook_stereo_mixers_t)tas3004_stereo_mixers,
  952. .output_device_change = (tas_hook_output_device_change_t)tas3004_output_device_change,
  953. .device_ioctl = (tas_hook_device_ioctl_t)tas3004_device_ioctl
  954. };