radio-sf16fmr2.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. /* SF16-FMR2 and SF16-FMD2 radio driver for Linux
  2. * Copyright (c) 2011 Ondrej Zary
  3. *
  4. * Original driver was (c) 2000-2002 Ziglio Frediano, freddy77@angelfire.com
  5. * but almost nothing remained here after conversion to generic TEA575x
  6. * implementation
  7. */
  8. #include <linux/delay.h>
  9. #include <linux/module.h> /* Modules */
  10. #include <linux/init.h> /* Initdata */
  11. #include <linux/slab.h>
  12. #include <linux/ioport.h> /* request_region */
  13. #include <linux/io.h> /* outb, outb_p */
  14. #include <linux/isa.h>
  15. #include <linux/pnp.h>
  16. #include <media/drv-intf/tea575x.h>
  17. MODULE_AUTHOR("Ondrej Zary");
  18. MODULE_DESCRIPTION("MediaForte SF16-FMR2 and SF16-FMD2 FM radio card driver");
  19. MODULE_LICENSE("GPL");
  20. /* these cards can only use two different ports (0x384 and 0x284) */
  21. #define FMR2_MAX 2
  22. static int radio_nr[FMR2_MAX] = { [0 ... (FMR2_MAX - 1)] = -1 };
  23. module_param_array(radio_nr, int, NULL, 0444);
  24. MODULE_PARM_DESC(radio_nr, "Radio device numbers");
  25. struct fmr2 {
  26. int io;
  27. struct v4l2_device v4l2_dev;
  28. struct snd_tea575x tea;
  29. struct v4l2_ctrl *volume;
  30. struct v4l2_ctrl *balance;
  31. bool is_fmd2;
  32. };
  33. static int num_fmr2_cards;
  34. static struct fmr2 *fmr2_cards[FMR2_MAX];
  35. static bool isa_registered;
  36. static bool pnp_registered;
  37. /* the port is hardwired on SF16-FMR2 */
  38. #define FMR2_PORT 0x384
  39. /* TEA575x tuner pins */
  40. #define STR_DATA (1 << 0)
  41. #define STR_CLK (1 << 1)
  42. #define STR_WREN (1 << 2)
  43. #define STR_MOST (1 << 3)
  44. /* PT2254A/TC9154A volume control pins */
  45. #define PT_ST (1 << 4)
  46. #define PT_CK (1 << 5)
  47. #define PT_DATA (1 << 6)
  48. /* volume control presence pin */
  49. #define FMR2_HASVOL (1 << 7)
  50. static void fmr2_tea575x_set_pins(struct snd_tea575x *tea, u8 pins)
  51. {
  52. struct fmr2 *fmr2 = tea->private_data;
  53. u8 bits = 0;
  54. bits |= (pins & TEA575X_DATA) ? STR_DATA : 0;
  55. bits |= (pins & TEA575X_CLK) ? STR_CLK : 0;
  56. /* WRITE_ENABLE is inverted, DATA must be high during read */
  57. bits |= (pins & TEA575X_WREN) ? 0 : STR_WREN | STR_DATA;
  58. outb(bits, fmr2->io);
  59. }
  60. static u8 fmr2_tea575x_get_pins(struct snd_tea575x *tea)
  61. {
  62. struct fmr2 *fmr2 = tea->private_data;
  63. u8 bits = inb(fmr2->io);
  64. return ((bits & STR_DATA) ? TEA575X_DATA : 0) |
  65. ((bits & STR_MOST) ? TEA575X_MOST : 0);
  66. }
  67. static void fmr2_tea575x_set_direction(struct snd_tea575x *tea, bool output)
  68. {
  69. }
  70. static const struct snd_tea575x_ops fmr2_tea_ops = {
  71. .set_pins = fmr2_tea575x_set_pins,
  72. .get_pins = fmr2_tea575x_get_pins,
  73. .set_direction = fmr2_tea575x_set_direction,
  74. };
  75. /* TC9154A/PT2254A volume control */
  76. /* 18-bit shift register bit definitions */
  77. #define TC9154A_ATT_MAJ_0DB (1 << 0)
  78. #define TC9154A_ATT_MAJ_10DB (1 << 1)
  79. #define TC9154A_ATT_MAJ_20DB (1 << 2)
  80. #define TC9154A_ATT_MAJ_30DB (1 << 3)
  81. #define TC9154A_ATT_MAJ_40DB (1 << 4)
  82. #define TC9154A_ATT_MAJ_50DB (1 << 5)
  83. #define TC9154A_ATT_MAJ_60DB (1 << 6)
  84. #define TC9154A_ATT_MIN_0DB (1 << 7)
  85. #define TC9154A_ATT_MIN_2DB (1 << 8)
  86. #define TC9154A_ATT_MIN_4DB (1 << 9)
  87. #define TC9154A_ATT_MIN_6DB (1 << 10)
  88. #define TC9154A_ATT_MIN_8DB (1 << 11)
  89. /* bit 12 is ignored */
  90. #define TC9154A_CHANNEL_LEFT (1 << 13)
  91. #define TC9154A_CHANNEL_RIGHT (1 << 14)
  92. /* bits 15, 16, 17 must be 0 */
  93. #define TC9154A_ATT_MAJ(x) (1 << x)
  94. #define TC9154A_ATT_MIN(x) (1 << (7 + x))
  95. static void tc9154a_set_pins(struct fmr2 *fmr2, u8 pins)
  96. {
  97. if (!fmr2->tea.mute)
  98. pins |= STR_WREN;
  99. outb(pins, fmr2->io);
  100. }
  101. static void tc9154a_set_attenuation(struct fmr2 *fmr2, int att, u32 channel)
  102. {
  103. int i;
  104. u32 reg;
  105. u8 bit;
  106. reg = TC9154A_ATT_MAJ(att / 10) | TC9154A_ATT_MIN((att % 10) / 2);
  107. reg |= channel;
  108. /* write 18-bit shift register, LSB first */
  109. for (i = 0; i < 18; i++) {
  110. bit = reg & (1 << i) ? PT_DATA : 0;
  111. tc9154a_set_pins(fmr2, bit);
  112. udelay(5);
  113. tc9154a_set_pins(fmr2, bit | PT_CK);
  114. udelay(5);
  115. tc9154a_set_pins(fmr2, bit);
  116. }
  117. /* latch register data */
  118. udelay(5);
  119. tc9154a_set_pins(fmr2, PT_ST);
  120. udelay(5);
  121. tc9154a_set_pins(fmr2, 0);
  122. }
  123. static int fmr2_s_ctrl(struct v4l2_ctrl *ctrl)
  124. {
  125. struct snd_tea575x *tea = container_of(ctrl->handler, struct snd_tea575x, ctrl_handler);
  126. struct fmr2 *fmr2 = tea->private_data;
  127. int volume, balance, left, right;
  128. switch (ctrl->id) {
  129. case V4L2_CID_AUDIO_VOLUME:
  130. volume = ctrl->val;
  131. balance = fmr2->balance->cur.val;
  132. break;
  133. case V4L2_CID_AUDIO_BALANCE:
  134. balance = ctrl->val;
  135. volume = fmr2->volume->cur.val;
  136. break;
  137. default:
  138. return -EINVAL;
  139. }
  140. left = right = volume;
  141. if (balance < 0)
  142. right = max(0, right + balance);
  143. if (balance > 0)
  144. left = max(0, left - balance);
  145. tc9154a_set_attenuation(fmr2, abs(left - 68), TC9154A_CHANNEL_LEFT);
  146. tc9154a_set_attenuation(fmr2, abs(right - 68), TC9154A_CHANNEL_RIGHT);
  147. return 0;
  148. }
  149. static const struct v4l2_ctrl_ops fmr2_ctrl_ops = {
  150. .s_ctrl = fmr2_s_ctrl,
  151. };
  152. static int fmr2_tea_ext_init(struct snd_tea575x *tea)
  153. {
  154. struct fmr2 *fmr2 = tea->private_data;
  155. /* FMR2 can have volume control, FMD2 can't (uses SB16 mixer) */
  156. if (!fmr2->is_fmd2 && inb(fmr2->io) & FMR2_HASVOL) {
  157. fmr2->volume = v4l2_ctrl_new_std(&tea->ctrl_handler, &fmr2_ctrl_ops, V4L2_CID_AUDIO_VOLUME, 0, 68, 2, 56);
  158. fmr2->balance = v4l2_ctrl_new_std(&tea->ctrl_handler, &fmr2_ctrl_ops, V4L2_CID_AUDIO_BALANCE, -68, 68, 2, 0);
  159. if (tea->ctrl_handler.error) {
  160. printk(KERN_ERR "radio-sf16fmr2: can't initialize controls\n");
  161. return tea->ctrl_handler.error;
  162. }
  163. }
  164. return 0;
  165. }
  166. static const struct pnp_device_id fmr2_pnp_ids[] = {
  167. { .id = "MFRad13" }, /* tuner subdevice of SF16-FMD2 */
  168. { .id = "" }
  169. };
  170. MODULE_DEVICE_TABLE(pnp, fmr2_pnp_ids);
  171. static int fmr2_probe(struct fmr2 *fmr2, struct device *pdev, int io)
  172. {
  173. int err, i;
  174. char *card_name = fmr2->is_fmd2 ? "SF16-FMD2" : "SF16-FMR2";
  175. /* avoid errors if a card was already registered at given port */
  176. for (i = 0; i < num_fmr2_cards; i++)
  177. if (io == fmr2_cards[i]->io)
  178. return -EBUSY;
  179. strlcpy(fmr2->v4l2_dev.name, "radio-sf16fmr2",
  180. sizeof(fmr2->v4l2_dev.name)),
  181. fmr2->io = io;
  182. if (!request_region(fmr2->io, 2, fmr2->v4l2_dev.name)) {
  183. printk(KERN_ERR "radio-sf16fmr2: I/O port 0x%x already in use\n", fmr2->io);
  184. return -EBUSY;
  185. }
  186. dev_set_drvdata(pdev, fmr2);
  187. err = v4l2_device_register(pdev, &fmr2->v4l2_dev);
  188. if (err < 0) {
  189. v4l2_err(&fmr2->v4l2_dev, "Could not register v4l2_device\n");
  190. release_region(fmr2->io, 2);
  191. return err;
  192. }
  193. fmr2->tea.v4l2_dev = &fmr2->v4l2_dev;
  194. fmr2->tea.private_data = fmr2;
  195. fmr2->tea.radio_nr = radio_nr[num_fmr2_cards];
  196. fmr2->tea.ops = &fmr2_tea_ops;
  197. fmr2->tea.ext_init = fmr2_tea_ext_init;
  198. strlcpy(fmr2->tea.card, card_name, sizeof(fmr2->tea.card));
  199. snprintf(fmr2->tea.bus_info, sizeof(fmr2->tea.bus_info), "%s:%s",
  200. fmr2->is_fmd2 ? "PnP" : "ISA", dev_name(pdev));
  201. if (snd_tea575x_init(&fmr2->tea, THIS_MODULE)) {
  202. printk(KERN_ERR "radio-sf16fmr2: Unable to detect TEA575x tuner\n");
  203. release_region(fmr2->io, 2);
  204. return -ENODEV;
  205. }
  206. printk(KERN_INFO "radio-sf16fmr2: %s radio card at 0x%x.\n",
  207. card_name, fmr2->io);
  208. return 0;
  209. }
  210. static int fmr2_isa_match(struct device *pdev, unsigned int ndev)
  211. {
  212. struct fmr2 *fmr2 = kzalloc(sizeof(*fmr2), GFP_KERNEL);
  213. if (!fmr2)
  214. return 0;
  215. if (fmr2_probe(fmr2, pdev, FMR2_PORT)) {
  216. kfree(fmr2);
  217. return 0;
  218. }
  219. dev_set_drvdata(pdev, fmr2);
  220. fmr2_cards[num_fmr2_cards++] = fmr2;
  221. return 1;
  222. }
  223. static int fmr2_pnp_probe(struct pnp_dev *pdev, const struct pnp_device_id *id)
  224. {
  225. int ret;
  226. struct fmr2 *fmr2 = kzalloc(sizeof(*fmr2), GFP_KERNEL);
  227. if (!fmr2)
  228. return -ENOMEM;
  229. fmr2->is_fmd2 = true;
  230. ret = fmr2_probe(fmr2, &pdev->dev, pnp_port_start(pdev, 0));
  231. if (ret) {
  232. kfree(fmr2);
  233. return ret;
  234. }
  235. pnp_set_drvdata(pdev, fmr2);
  236. fmr2_cards[num_fmr2_cards++] = fmr2;
  237. return 0;
  238. }
  239. static void fmr2_remove(struct fmr2 *fmr2)
  240. {
  241. snd_tea575x_exit(&fmr2->tea);
  242. release_region(fmr2->io, 2);
  243. v4l2_device_unregister(&fmr2->v4l2_dev);
  244. kfree(fmr2);
  245. }
  246. static int fmr2_isa_remove(struct device *pdev, unsigned int ndev)
  247. {
  248. fmr2_remove(dev_get_drvdata(pdev));
  249. return 0;
  250. }
  251. static void fmr2_pnp_remove(struct pnp_dev *pdev)
  252. {
  253. fmr2_remove(pnp_get_drvdata(pdev));
  254. pnp_set_drvdata(pdev, NULL);
  255. }
  256. static struct isa_driver fmr2_isa_driver = {
  257. .match = fmr2_isa_match,
  258. .remove = fmr2_isa_remove,
  259. .driver = {
  260. .name = "radio-sf16fmr2",
  261. },
  262. };
  263. static struct pnp_driver fmr2_pnp_driver = {
  264. .name = "radio-sf16fmr2",
  265. .id_table = fmr2_pnp_ids,
  266. .probe = fmr2_pnp_probe,
  267. .remove = fmr2_pnp_remove,
  268. };
  269. static int __init fmr2_init(void)
  270. {
  271. int ret;
  272. ret = pnp_register_driver(&fmr2_pnp_driver);
  273. if (!ret)
  274. pnp_registered = true;
  275. ret = isa_register_driver(&fmr2_isa_driver, 1);
  276. if (!ret)
  277. isa_registered = true;
  278. return (pnp_registered || isa_registered) ? 0 : ret;
  279. }
  280. static void __exit fmr2_exit(void)
  281. {
  282. if (pnp_registered)
  283. pnp_unregister_driver(&fmr2_pnp_driver);
  284. if (isa_registered)
  285. isa_unregister_driver(&fmr2_isa_driver);
  286. }
  287. module_init(fmr2_init);
  288. module_exit(fmr2_exit);