dac3550a.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:6k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * Driver for the i2c/i2s based DAC3550a sound chip used
  3.  * on some Apple iBooks. Also known as "DACA".
  4.  *
  5.  *  This file is subject to the terms and conditions of the GNU General Public
  6.  *  License.  See the file COPYING in the main directory of this archive
  7.  *  for more details.
  8.  */
  9. #include <linux/version.h>
  10. #include <linux/module.h>
  11. #include <linux/slab.h>
  12. #include <linux/proc_fs.h>
  13. #include <linux/ioport.h>
  14. #include <linux/sysctl.h>
  15. #include <linux/types.h>
  16. #include <linux/i2c.h>
  17. #include <linux/init.h>
  18. #include <asm/uaccess.h>
  19. #include <asm/errno.h>
  20. #include <asm/io.h>
  21. #include "dmasound.h"
  22. /* FYI: This code was derived from the tas3001c.c Texas/Tumbler mixer
  23.  * control code, as well as info derived from the AppleDACAAudio driver
  24.  * from Darwin CVS (main thing I derived being register numbers and 
  25.  * values, as well as when to make the calls). */
  26. #define I2C_DRIVERID_DACA (0xFDCB)
  27. #define DACA_VERSION "0.1"
  28. #define DACA_DATE "20010930"
  29. static int cur_left_vol;
  30. static int cur_right_vol;
  31. static struct i2c_client * daca_client = NULL;
  32. static int daca_attach_adapter(struct i2c_adapter *adapter);
  33. static int daca_attach_adapter(struct i2c_adapter *adapter);
  34. static int daca_detect_client(struct i2c_adapter *adapter, int address);
  35. static int daca_detach_client(struct i2c_client *client);
  36. /* Unique ID allocation */
  37. static int daca_id;
  38. static int daca_initialized;
  39. struct daca_data
  40. {
  41. int arf; /* place holder for furture use */
  42. };
  43. struct i2c_driver daca_driver = {  
  44. name: "DAC3550A driver  V " DACA_VERSION,
  45. id: I2C_DRIVERID_DACA,
  46. flags: I2C_DF_NOTIFY,
  47. attach_adapter: &daca_attach_adapter,
  48. detach_client: &daca_detach_client,
  49. command: NULL,
  50. inc_use: NULL, /* &daca_inc_use, */
  51. dec_use: NULL  /* &daca_dev_use  */
  52.   };
  53. #define VOL_MAX ((1<<20) - 1)
  54. void
  55. daca_get_volume(uint * left_vol, uint  *right_vol)
  56. {
  57. *left_vol = cur_left_vol >> 5;
  58. *right_vol = cur_right_vol >> 5;
  59. }
  60. int
  61. daca_set_volume(uint left_vol, uint right_vol)
  62. {
  63. unsigned short voldata;
  64.   
  65. if (!daca_client)
  66. return -1;
  67. /* Derived from experience, not from any specific values */
  68. left_vol <<= 5;
  69. right_vol <<= 5;
  70. if (left_vol > VOL_MAX)
  71. left_vol = VOL_MAX;
  72. if (right_vol > VOL_MAX)
  73. right_vol = VOL_MAX;
  74. voldata = ((left_vol >> 14)  & 0x3f) << 8;
  75. voldata |= (right_vol >> 14)  & 0x3f;
  76.   
  77. if (i2c_smbus_write_word_data(daca_client, 2, voldata) < 0) {
  78. printk("daca: failed to set volume n");
  79. return -1; 
  80. }
  81. cur_left_vol = left_vol;
  82. cur_right_vol = right_vol;
  83.   
  84. return 0;
  85. }
  86. int
  87. daca_leave_sleep(void)
  88. {
  89. if (!daca_client)
  90. return -1;
  91.   
  92. /* Do a short sleep, just to make sure I2C bus is awake and paying
  93.  * attention to us
  94.  */
  95. wait_ms(20);
  96. /* Write the sample rate reg the value it needs */
  97. i2c_smbus_write_byte_data(daca_client, 1, 8);
  98. daca_set_volume(cur_left_vol >> 5, cur_right_vol >> 5);
  99. /* Another short delay, just to make sure the other I2C bus writes
  100.  * have taken...
  101.  */
  102. wait_ms(20);
  103. /* Write the global config reg - invert right power amp,
  104.  * DAC on, use 5-volt mode */
  105. i2c_smbus_write_byte_data(daca_client, 3, 0x45);
  106. return 0;
  107. }
  108. int
  109. daca_enter_sleep(void)
  110. {
  111. if (!daca_client)
  112. return -1;
  113. i2c_smbus_write_byte_data(daca_client, 1, 8);
  114. daca_set_volume(cur_left_vol >> 5, cur_right_vol >> 5);
  115. /* Write the global config reg - invert right power amp,
  116.  * DAC on, enter low-power mode, use 5-volt mode
  117.  */
  118. i2c_smbus_write_byte_data(daca_client, 3, 0x65);
  119. return 0;
  120. }
  121. static int
  122. daca_attach_adapter(struct i2c_adapter *adapter)
  123. {
  124. if (!strncmp(adapter->name, "mac-io", 6))
  125. daca_detect_client(adapter, 0x4d);
  126. return 0;
  127. }
  128. static int
  129. daca_init_client(struct i2c_client * new_client)
  130. {
  131. /* 
  132.  * Probe is not working with the current i2c-keywest
  133.  * driver. We try to use addr 0x4d on each adapters
  134.  * instead, by setting the format register.
  135.  * 
  136.  * FIXME: I'm sure that can be obtained from the
  137.  * device-tree. --BenH.
  138.  */
  139.   
  140. /* Write the global config reg - invert right power amp,
  141.  * DAC on, use 5-volt mode
  142.  */
  143. if (i2c_smbus_write_byte_data(new_client, 3, 0x45))
  144. return -1;
  145. i2c_smbus_write_byte_data(new_client, 1, 8);
  146. daca_client = new_client;
  147. daca_set_volume(15000, 15000);
  148. return 0;
  149. }
  150. static int
  151. daca_detect_client(struct i2c_adapter *adapter, int address)
  152. {
  153. int rc = 0;
  154. struct i2c_client *new_client;
  155. struct daca_data *data;
  156. const char *client_name = "DAC 3550A Digital Equalizer";
  157. new_client = kmalloc(
  158. sizeof(struct i2c_client) + sizeof(struct daca_data),
  159. GFP_KERNEL);
  160. if (!new_client) {
  161. rc = -ENOMEM;
  162. goto bail;
  163. }
  164. /* This is tricky, but it will set the data to the right value. */
  165. new_client->data = new_client + 1;
  166. data = (struct daca_data *) (new_client->data);
  167. new_client->addr = address;
  168. new_client->data = data;
  169. new_client->adapter = adapter;
  170. new_client->driver = &daca_driver;
  171. new_client->flags = 0;
  172. strcpy(new_client->name,client_name);
  173. new_client->id = daca_id++; /* Automatically unique */
  174.   
  175. if (daca_init_client(new_client)) {
  176. rc = -ENODEV;
  177. goto bail;
  178. }
  179. /* Tell the i2c layer a new client has arrived */
  180. if (i2c_attach_client(new_client)) {
  181. rc = -ENODEV;
  182. goto bail;
  183. }
  184. bail:
  185. if (rc && new_client)
  186. kfree(new_client);
  187. return rc;
  188. }
  189. static int
  190. daca_detach_client(struct i2c_client *client)
  191. {
  192. if (client == daca_client)
  193. daca_client = NULL;
  194.    i2c_detach_client(client);
  195. kfree(client);
  196. return 0;
  197. }
  198. int
  199. daca_cleanup(void)
  200. {
  201. if (!daca_initialized)
  202. return -ENODEV;
  203. i2c_del_driver(&daca_driver);
  204. daca_initialized = 0;
  205. return 0;
  206. }
  207. int
  208. daca_init(void)
  209. {
  210. int rc;
  211. if (daca_initialized)
  212. return 0;
  213. printk("dac3550a driver version %s (%s)n",DACA_VERSION,DACA_DATE);
  214.     
  215. if ((rc = i2c_add_driver(&daca_driver))) {
  216. printk("dac3550a: Driver registration failed, module not inserted.n");
  217. daca_cleanup();
  218. return rc;
  219. }
  220. daca_initialized = 1;
  221. return 0;
  222. }