tas_common.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. #ifndef _TAS_COMMON_H_
  2. #define _TAS_COMMON_H_
  3. #include <linux/i2c.h>
  4. #include <linux/soundcard.h>
  5. #include <asm/string.h>
  6. #define I2C_DRIVERID_TAS_BASE (0xFEBA)
  7. #define SET_4_20(shadow, offset, val) \
  8. do { \
  9. (shadow)[(offset)+0] = ((val) >> 16) & 0xff; \
  10. (shadow)[(offset)+1] = ((val) >> 8) & 0xff; \
  11. (shadow)[(offset)+2] = ((val) >> 0) & 0xff; \
  12. } while (0)
  13. #define GET_4_20(shadow, offset) \
  14. (((u_int)((shadow)[(offset)+0]) << 16) | \
  15. ((u_int)((shadow)[(offset)+1]) << 8) | \
  16. ((u_int)((shadow)[(offset)+2]) << 0))
  17. #define TAS_BIQUAD_FAST_LOAD 0x01
  18. #define TAS_DRCE_ENABLE 0x01
  19. #define TAS_DRCE_ABOVE_RATIO 0x02
  20. #define TAS_DRCE_BELOW_RATIO 0x04
  21. #define TAS_DRCE_THRESHOLD 0x08
  22. #define TAS_DRCE_ENERGY 0x10
  23. #define TAS_DRCE_ATTACK 0x20
  24. #define TAS_DRCE_DECAY 0x40
  25. #define TAS_DRCE_ALL 0x7f
  26. #define TAS_OUTPUT_HEADPHONES 0x00
  27. #define TAS_OUTPUT_INTERNAL_SPKR 0x01
  28. #define TAS_OUTPUT_EXTERNAL_SPKR 0x02
  29. union tas_biquad_t {
  30. struct {
  31. int b0,b1,b2,a1,a2;
  32. } coeff;
  33. int buf[5];
  34. };
  35. struct tas_biquad_ctrl_t {
  36. u_int channel:4;
  37. u_int filter:4;
  38. union tas_biquad_t data;
  39. };
  40. struct tas_biquad_ctrl_list_t {
  41. int flags;
  42. int filter_count;
  43. struct tas_biquad_ctrl_t biquads[0];
  44. };
  45. struct tas_ratio_t {
  46. unsigned short val; /* 8.8 */
  47. unsigned short expand; /* 0 = compress, !0 = expand. */
  48. };
  49. struct tas_drce_t {
  50. unsigned short enable;
  51. struct tas_ratio_t above;
  52. struct tas_ratio_t below;
  53. short threshold; /* dB, 8.8 signed */
  54. unsigned short energy; /* seconds, 4.12 unsigned */
  55. unsigned short attack; /* seconds, 4.12 unsigned */
  56. unsigned short decay; /* seconds, 4.12 unsigned */
  57. };
  58. struct tas_drce_ctrl_t {
  59. uint flags;
  60. struct tas_drce_t data;
  61. };
  62. struct tas_gain_t
  63. {
  64. unsigned int *master;
  65. unsigned int *treble;
  66. unsigned int *bass;
  67. unsigned int *mixer;
  68. };
  69. typedef char tas_shadow_t[0x45];
  70. struct tas_data_t
  71. {
  72. struct i2c_client *client;
  73. tas_shadow_t *shadow;
  74. uint mixer[SOUND_MIXER_NRDEVICES];
  75. };
  76. typedef int (*tas_hook_init_t)(struct i2c_client *);
  77. typedef int (*tas_hook_post_init_t)(struct tas_data_t *);
  78. typedef void (*tas_hook_uninit_t)(struct tas_data_t *);
  79. typedef int (*tas_hook_get_mixer_level_t)(struct tas_data_t *,int,uint *);
  80. typedef int (*tas_hook_set_mixer_level_t)(struct tas_data_t *,int,uint);
  81. typedef int (*tas_hook_enter_sleep_t)(struct tas_data_t *);
  82. typedef int (*tas_hook_leave_sleep_t)(struct tas_data_t *);
  83. typedef int (*tas_hook_supported_mixers_t)(struct tas_data_t *);
  84. typedef int (*tas_hook_mixer_is_stereo_t)(struct tas_data_t *,int);
  85. typedef int (*tas_hook_stereo_mixers_t)(struct tas_data_t *);
  86. typedef int (*tas_hook_output_device_change_t)(struct tas_data_t *,int,int,int);
  87. typedef int (*tas_hook_device_ioctl_t)(struct tas_data_t *,u_int,u_long);
  88. struct tas_driver_hooks_t {
  89. /*
  90. * All hardware initialisation must be performed in
  91. * post_init(), as tas_dmasound_init() does a hardware reset.
  92. *
  93. * init() is called before tas_dmasound_init() so that
  94. * ouput_device_change() is always called after i2c driver
  95. * initialisation. The implication is that
  96. * output_device_change() must cope with the fact that it
  97. * may be called before post_init().
  98. */
  99. tas_hook_init_t init;
  100. tas_hook_post_init_t post_init;
  101. tas_hook_uninit_t uninit;
  102. tas_hook_get_mixer_level_t get_mixer_level;
  103. tas_hook_set_mixer_level_t set_mixer_level;
  104. tas_hook_enter_sleep_t enter_sleep;
  105. tas_hook_leave_sleep_t leave_sleep;
  106. tas_hook_supported_mixers_t supported_mixers;
  107. tas_hook_mixer_is_stereo_t mixer_is_stereo;
  108. tas_hook_stereo_mixers_t stereo_mixers;
  109. tas_hook_output_device_change_t output_device_change;
  110. tas_hook_device_ioctl_t device_ioctl;
  111. };
  112. enum tas_write_mode_t {
  113. WRITE_HW = 0x01,
  114. WRITE_SHADOW = 0x02,
  115. WRITE_NORMAL = 0x03,
  116. FORCE_WRITE = 0x04
  117. };
  118. static inline uint
  119. tas_mono_to_stereo(uint mono)
  120. {
  121. mono &=0xff;
  122. return mono | (mono<<8);
  123. }
  124. /*
  125. * Todo: make these functions a bit more efficient !
  126. */
  127. static inline int
  128. tas_write_register( struct tas_data_t *self,
  129. uint reg_num,
  130. uint reg_width,
  131. char *data,
  132. uint write_mode)
  133. {
  134. int rc;
  135. if (reg_width==0 || data==NULL || self==NULL)
  136. return -EINVAL;
  137. if (!(write_mode & FORCE_WRITE) &&
  138. !memcmp(data,self->shadow[reg_num],reg_width))
  139. return 0;
  140. if (write_mode & WRITE_SHADOW)
  141. memcpy(self->shadow[reg_num],data,reg_width);
  142. if (write_mode & WRITE_HW) {
  143. rc=i2c_smbus_write_block_data(self->client,
  144. reg_num,
  145. reg_width,
  146. data);
  147. if (rc < 0) {
  148. printk("tas: I2C block write failed \n");
  149. return rc;
  150. }
  151. }
  152. return 0;
  153. }
  154. static inline int
  155. tas_sync_register( struct tas_data_t *self,
  156. uint reg_num,
  157. uint reg_width)
  158. {
  159. int rc;
  160. if (reg_width==0 || self==NULL)
  161. return -EINVAL;
  162. rc=i2c_smbus_write_block_data(self->client,
  163. reg_num,
  164. reg_width,
  165. self->shadow[reg_num]);
  166. if (rc < 0) {
  167. printk("tas: I2C block write failed \n");
  168. return rc;
  169. }
  170. return 0;
  171. }
  172. static inline int
  173. tas_write_byte_register( struct tas_data_t *self,
  174. uint reg_num,
  175. char data,
  176. uint write_mode)
  177. {
  178. if (self==NULL)
  179. return -1;
  180. if (!(write_mode & FORCE_WRITE) && data != self->shadow[reg_num][0])
  181. return 0;
  182. if (write_mode & WRITE_SHADOW)
  183. self->shadow[reg_num][0]=data;
  184. if (write_mode & WRITE_HW) {
  185. if (i2c_smbus_write_byte_data(self->client, reg_num, data) < 0) {
  186. printk("tas: I2C byte write failed \n");
  187. return -1;
  188. }
  189. }
  190. return 0;
  191. }
  192. static inline int
  193. tas_sync_byte_register( struct tas_data_t *self,
  194. uint reg_num,
  195. uint reg_width)
  196. {
  197. if (reg_width==0 || self==NULL)
  198. return -1;
  199. if (i2c_smbus_write_byte_data(
  200. self->client, reg_num, self->shadow[reg_num][0]) < 0) {
  201. printk("tas: I2C byte write failed \n");
  202. return -1;
  203. }
  204. return 0;
  205. }
  206. static inline int
  207. tas_read_register( struct tas_data_t *self,
  208. uint reg_num,
  209. uint reg_width,
  210. char *data)
  211. {
  212. if (reg_width==0 || data==NULL || self==NULL)
  213. return -1;
  214. memcpy(data,self->shadow[reg_num],reg_width);
  215. return 0;
  216. }
  217. extern int tas_register_driver(struct tas_driver_hooks_t *hooks);
  218. extern int tas_get_mixer_level(int mixer,uint *level);
  219. extern int tas_set_mixer_level(int mixer,uint level);
  220. extern int tas_enter_sleep(void);
  221. extern int tas_leave_sleep(void);
  222. extern int tas_supported_mixers(void);
  223. extern int tas_mixer_is_stereo(int mixer);
  224. extern int tas_stereo_mixers(void);
  225. extern int tas_output_device_change(int,int,int);
  226. extern int tas_device_ioctl(u_int, u_long);
  227. extern void tas_cleanup(void);
  228. extern int tas_init(int driver_id,const char *driver_name);
  229. extern int tas_post_init(void);
  230. #endif /* _TAS_COMMON_H_ */
  231. /*
  232. * Local Variables:
  233. * tab-width: 8
  234. * indent-tabs-mode: t
  235. * c-basic-offset: 8
  236. * End:
  237. */