tvmixer.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. /*
  2. */
  3. #include <linux/module.h>
  4. #include <linux/moduleparam.h>
  5. #include <linux/kernel.h>
  6. #include <linux/string.h>
  7. #include <linux/timer.h>
  8. #include <linux/delay.h>
  9. #include <linux/errno.h>
  10. #include <linux/slab.h>
  11. #include <linux/i2c.h>
  12. #include <linux/videodev.h>
  13. #include <linux/init.h>
  14. #include <linux/kdev_t.h>
  15. #include <linux/sound.h>
  16. #include <linux/soundcard.h>
  17. #include <asm/semaphore.h>
  18. #include <asm/uaccess.h>
  19. #define DEV_MAX 4
  20. static int devnr = -1;
  21. module_param(devnr, int, 0644);
  22. MODULE_AUTHOR("Gerd Knorr");
  23. MODULE_LICENSE("GPL");
  24. /* ----------------------------------------------------------------------- */
  25. struct TVMIXER {
  26. struct i2c_client *dev;
  27. int minor;
  28. int count;
  29. };
  30. static struct TVMIXER devices[DEV_MAX];
  31. static int tvmixer_adapters(struct i2c_adapter *adap);
  32. static int tvmixer_clients(struct i2c_client *client);
  33. /* ----------------------------------------------------------------------- */
  34. static int mix_to_v4l(int i)
  35. {
  36. int r;
  37. r = ((i & 0xff) * 65536 + 50) / 100;
  38. if (r > 65535) r = 65535;
  39. if (r < 0) r = 0;
  40. return r;
  41. }
  42. static int v4l_to_mix(int i)
  43. {
  44. int r;
  45. r = (i * 100 + 32768) / 65536;
  46. if (r > 100) r = 100;
  47. if (r < 0) r = 0;
  48. return r | (r << 8);
  49. }
  50. static int v4l_to_mix2(int l, int r)
  51. {
  52. r = (r * 100 + 32768) / 65536;
  53. if (r > 100) r = 100;
  54. if (r < 0) r = 0;
  55. l = (l * 100 + 32768) / 65536;
  56. if (l > 100) l = 100;
  57. if (l < 0) l = 0;
  58. return (r << 8) | l;
  59. }
  60. static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
  61. {
  62. struct video_audio va;
  63. int left,right,ret,val = 0;
  64. struct TVMIXER *mix = file->private_data;
  65. struct i2c_client *client = mix->dev;
  66. void __user *argp = (void __user *)arg;
  67. int __user *p = argp;
  68. if (NULL == client)
  69. return -ENODEV;
  70. if (cmd == SOUND_MIXER_INFO) {
  71. mixer_info info;
  72. strlcpy(info.id, "tv card", sizeof(info.id));
  73. strlcpy(info.name, client->name, sizeof(info.name));
  74. info.modify_counter = 42 /* FIXME */;
  75. if (copy_to_user(argp, &info, sizeof(info)))
  76. return -EFAULT;
  77. return 0;
  78. }
  79. if (cmd == SOUND_OLD_MIXER_INFO) {
  80. _old_mixer_info info;
  81. strlcpy(info.id, "tv card", sizeof(info.id));
  82. strlcpy(info.name, client->name, sizeof(info.name));
  83. if (copy_to_user(argp, &info, sizeof(info)))
  84. return -EFAULT;
  85. return 0;
  86. }
  87. if (cmd == OSS_GETVERSION)
  88. return put_user(SOUND_VERSION, p);
  89. if (_SIOC_DIR(cmd) & _SIOC_WRITE)
  90. if (get_user(val, p))
  91. return -EFAULT;
  92. /* read state */
  93. memset(&va,0,sizeof(va));
  94. client->driver->command(client,VIDIOCGAUDIO,&va);
  95. switch (cmd) {
  96. case MIXER_READ(SOUND_MIXER_RECMASK):
  97. case MIXER_READ(SOUND_MIXER_CAPS):
  98. case MIXER_READ(SOUND_MIXER_RECSRC):
  99. case MIXER_WRITE(SOUND_MIXER_RECSRC):
  100. ret = 0;
  101. break;
  102. case MIXER_READ(SOUND_MIXER_STEREODEVS):
  103. ret = SOUND_MASK_VOLUME;
  104. break;
  105. case MIXER_READ(SOUND_MIXER_DEVMASK):
  106. ret = SOUND_MASK_VOLUME;
  107. if (va.flags & VIDEO_AUDIO_BASS)
  108. ret |= SOUND_MASK_BASS;
  109. if (va.flags & VIDEO_AUDIO_TREBLE)
  110. ret |= SOUND_MASK_TREBLE;
  111. break;
  112. case MIXER_WRITE(SOUND_MIXER_VOLUME):
  113. left = mix_to_v4l(val);
  114. right = mix_to_v4l(val >> 8);
  115. va.volume = max(left,right);
  116. va.balance = (32768*min(left,right)) / (va.volume ? va.volume : 1);
  117. va.balance = (left<right) ? (65535-va.balance) : va.balance;
  118. if (va.volume)
  119. va.flags &= ~VIDEO_AUDIO_MUTE;
  120. client->driver->command(client,VIDIOCSAUDIO,&va);
  121. client->driver->command(client,VIDIOCGAUDIO,&va);
  122. /* fall throuth */
  123. case MIXER_READ(SOUND_MIXER_VOLUME):
  124. left = (min(65536 - va.balance,32768) *
  125. va.volume) / 32768;
  126. right = (min(va.balance,(u16)32768) *
  127. va.volume) / 32768;
  128. ret = v4l_to_mix2(left,right);
  129. break;
  130. case MIXER_WRITE(SOUND_MIXER_BASS):
  131. va.bass = mix_to_v4l(val);
  132. client->driver->command(client,VIDIOCSAUDIO,&va);
  133. client->driver->command(client,VIDIOCGAUDIO,&va);
  134. /* fall throuth */
  135. case MIXER_READ(SOUND_MIXER_BASS):
  136. ret = v4l_to_mix(va.bass);
  137. break;
  138. case MIXER_WRITE(SOUND_MIXER_TREBLE):
  139. va.treble = mix_to_v4l(val);
  140. client->driver->command(client,VIDIOCSAUDIO,&va);
  141. client->driver->command(client,VIDIOCGAUDIO,&va);
  142. /* fall throuth */
  143. case MIXER_READ(SOUND_MIXER_TREBLE):
  144. ret = v4l_to_mix(va.treble);
  145. break;
  146. default:
  147. return -EINVAL;
  148. }
  149. if (put_user(ret, p))
  150. return -EFAULT;
  151. return 0;
  152. }
  153. static int tvmixer_open(struct inode *inode, struct file *file)
  154. {
  155. int i, minor = iminor(inode);
  156. struct TVMIXER *mix = NULL;
  157. struct i2c_client *client = NULL;
  158. for (i = 0; i < DEV_MAX; i++) {
  159. if (devices[i].minor == minor) {
  160. mix = devices+i;
  161. client = mix->dev;
  162. break;
  163. }
  164. }
  165. if (NULL == client)
  166. return -ENODEV;
  167. /* lock bttv in memory while the mixer is in use */
  168. file->private_data = mix;
  169. if (client->adapter->owner)
  170. try_module_get(client->adapter->owner);
  171. return 0;
  172. }
  173. static int tvmixer_release(struct inode *inode, struct file *file)
  174. {
  175. struct TVMIXER *mix = file->private_data;
  176. struct i2c_client *client;
  177. client = mix->dev;
  178. if (NULL == client) {
  179. return -ENODEV;
  180. }
  181. module_put(client->adapter->owner);
  182. return 0;
  183. }
  184. static struct i2c_driver driver = {
  185. .driver = {
  186. .name = "tvmixer",
  187. },
  188. .id = I2C_DRIVERID_TVMIXER,
  189. .detach_adapter = tvmixer_adapters,
  190. .attach_adapter = tvmixer_adapters,
  191. .detach_client = tvmixer_clients,
  192. };
  193. static const struct file_operations tvmixer_fops = {
  194. .owner = THIS_MODULE,
  195. .llseek = no_llseek,
  196. .ioctl = tvmixer_ioctl,
  197. .open = tvmixer_open,
  198. .release = tvmixer_release,
  199. };
  200. /* ----------------------------------------------------------------------- */
  201. static int tvmixer_adapters(struct i2c_adapter *adap)
  202. {
  203. struct list_head *item;
  204. struct i2c_client *client;
  205. list_for_each(item,&adap->clients) {
  206. client = list_entry(item, struct i2c_client, list);
  207. tvmixer_clients(client);
  208. }
  209. return 0;
  210. }
  211. static int tvmixer_clients(struct i2c_client *client)
  212. {
  213. struct video_audio va;
  214. int i,minor;
  215. if (!(client->adapter->class & I2C_CLASS_TV_ANALOG))
  216. return -1;
  217. /* unregister ?? */
  218. for (i = 0; i < DEV_MAX; i++) {
  219. if (devices[i].dev == client) {
  220. /* unregister */
  221. unregister_sound_mixer(devices[i].minor);
  222. devices[i].dev = NULL;
  223. devices[i].minor = -1;
  224. printk("tvmixer: %s unregistered (#1)\n",
  225. client->name);
  226. return 0;
  227. }
  228. }
  229. /* look for a free slot */
  230. for (i = 0; i < DEV_MAX; i++)
  231. if (NULL == devices[i].dev)
  232. break;
  233. if (i == DEV_MAX) {
  234. printk(KERN_WARNING "tvmixer: DEV_MAX too small\n");
  235. return -1;
  236. }
  237. /* audio chip with mixer ??? */
  238. if (NULL == client->driver->command)
  239. return -1;
  240. memset(&va,0,sizeof(va));
  241. if (0 != client->driver->command(client,VIDIOCGAUDIO,&va))
  242. return -1;
  243. if (0 == (va.flags & VIDEO_AUDIO_VOLUME))
  244. return -1;
  245. /* everything is fine, register */
  246. if ((minor = register_sound_mixer(&tvmixer_fops,devnr)) < 0) {
  247. printk(KERN_ERR "tvmixer: cannot allocate mixer device\n");
  248. return -1;
  249. }
  250. devices[i].minor = minor;
  251. devices[i].count = 0;
  252. devices[i].dev = client;
  253. printk("tvmixer: %s (%s) registered with minor %d\n",
  254. client->name,client->adapter->name,minor);
  255. return 0;
  256. }
  257. /* ----------------------------------------------------------------------- */
  258. static int __init tvmixer_init_module(void)
  259. {
  260. int i;
  261. for (i = 0; i < DEV_MAX; i++)
  262. devices[i].minor = -1;
  263. return i2c_add_driver(&driver);
  264. }
  265. static void __exit tvmixer_cleanup_module(void)
  266. {
  267. int i;
  268. i2c_del_driver(&driver);
  269. for (i = 0; i < DEV_MAX; i++) {
  270. if (devices[i].minor != -1) {
  271. unregister_sound_mixer(devices[i].minor);
  272. printk("tvmixer: %s unregistered (#2)\n",
  273. devices[i].dev->name);
  274. }
  275. }
  276. }
  277. module_init(tvmixer_init_module);
  278. module_exit(tvmixer_cleanup_module);
  279. /*
  280. * Overrides for Emacs so that we follow Linus's tabbing style.
  281. * ---------------------------------------------------------------------------
  282. * Local variables:
  283. * c-basic-offset: 8
  284. * End:
  285. */