tas3004.c 28 KB

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