tuner-core.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. /*
  2. * $Id: tuner-core.c,v 1.5 2005/02/15 15:59:35 kraxel Exp $
  3. *
  4. * i2c tv tuner chip device driver
  5. * core core, i.e. kernel interfaces, registering and so on
  6. */
  7. #include <linux/module.h>
  8. #include <linux/moduleparam.h>
  9. #include <linux/kernel.h>
  10. #include <linux/sched.h>
  11. #include <linux/string.h>
  12. #include <linux/timer.h>
  13. #include <linux/delay.h>
  14. #include <linux/errno.h>
  15. #include <linux/slab.h>
  16. #include <linux/poll.h>
  17. #include <linux/i2c.h>
  18. #include <linux/types.h>
  19. #include <linux/videodev.h>
  20. #include <linux/init.h>
  21. #include <media/tuner.h>
  22. #include <media/audiochip.h>
  23. #define UNSET (-1U)
  24. /* standard i2c insmod options */
  25. static unsigned short normal_i2c[] = {
  26. 0x4b, /* tda8290 */
  27. I2C_CLIENT_END
  28. };
  29. static unsigned short normal_i2c_range[] = {
  30. 0x60, 0x6f,
  31. I2C_CLIENT_END
  32. };
  33. I2C_CLIENT_INSMOD;
  34. /* insmod options used at init time => read/only */
  35. static unsigned int addr = 0;
  36. module_param(addr, int, 0444);
  37. /* insmod options used at runtime => read/write */
  38. unsigned int tuner_debug = 0;
  39. module_param(tuner_debug, int, 0644);
  40. static unsigned int tv_range[2] = { 44, 958 };
  41. static unsigned int radio_range[2] = { 65, 108 };
  42. module_param_array(tv_range, int, NULL, 0644);
  43. module_param_array(radio_range, int, NULL, 0644);
  44. MODULE_DESCRIPTION("device driver for various TV and TV+FM radio tuners");
  45. MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
  46. MODULE_LICENSE("GPL");
  47. static int this_adap;
  48. static struct i2c_driver driver;
  49. static struct i2c_client client_template;
  50. /* ---------------------------------------------------------------------- */
  51. // Set tuner frequency, freq in Units of 62.5kHz = 1/16MHz
  52. static void set_tv_freq(struct i2c_client *c, unsigned int freq)
  53. {
  54. struct tuner *t = i2c_get_clientdata(c);
  55. if (t->type == UNSET) {
  56. tuner_info("tuner type not set\n");
  57. return;
  58. }
  59. if (NULL == t->tv_freq) {
  60. tuner_info("Huh? tv_set is NULL?\n");
  61. return;
  62. }
  63. if (freq < tv_range[0]*16 || freq > tv_range[1]*16) {
  64. /* FIXME: better do that chip-specific, but
  65. right now we don't have that in the config
  66. struct and this way is still better than no
  67. check at all */
  68. tuner_info("TV freq (%d.%02d) out of range (%d-%d)\n",
  69. freq/16,freq%16*100/16,tv_range[0],tv_range[1]);
  70. return;
  71. }
  72. t->tv_freq(c,freq);
  73. }
  74. static void set_radio_freq(struct i2c_client *c, unsigned int freq)
  75. {
  76. struct tuner *t = i2c_get_clientdata(c);
  77. if (t->type == UNSET) {
  78. tuner_info("tuner type not set\n");
  79. return;
  80. }
  81. if (NULL == t->radio_freq) {
  82. tuner_info("no radio tuning for this one, sorry.\n");
  83. return;
  84. }
  85. if (freq < radio_range[0]*16 || freq > radio_range[1]*16) {
  86. tuner_info("radio freq (%d.%02d) out of range (%d-%d)\n",
  87. freq/16,freq%16*100/16,
  88. radio_range[0],radio_range[1]);
  89. return;
  90. }
  91. t->radio_freq(c,freq);
  92. }
  93. static void set_freq(struct i2c_client *c, unsigned long freq)
  94. {
  95. struct tuner *t = i2c_get_clientdata(c);
  96. switch (t->mode) {
  97. case V4L2_TUNER_RADIO:
  98. tuner_dbg("radio freq set to %lu.%02lu\n",
  99. freq/16,freq%16*100/16);
  100. set_radio_freq(c,freq);
  101. break;
  102. case V4L2_TUNER_ANALOG_TV:
  103. case V4L2_TUNER_DIGITAL_TV:
  104. tuner_dbg("tv freq set to %lu.%02lu\n",
  105. freq/16,freq%16*100/16);
  106. set_tv_freq(c, freq);
  107. break;
  108. }
  109. t->freq = freq;
  110. }
  111. static void set_type(struct i2c_client *c, unsigned int type)
  112. {
  113. struct tuner *t = i2c_get_clientdata(c);
  114. /* sanity check */
  115. if (type == UNSET || type == TUNER_ABSENT)
  116. return;
  117. if (type >= tuner_count)
  118. return;
  119. if (NULL == t->i2c.dev.driver) {
  120. /* not registered yet */
  121. t->type = type;
  122. return;
  123. }
  124. if (t->initialized)
  125. /* run only once */
  126. return;
  127. t->initialized = 1;
  128. t->type = type;
  129. switch (t->type) {
  130. case TUNER_MT2032:
  131. microtune_init(c);
  132. break;
  133. case TUNER_PHILIPS_TDA8290:
  134. tda8290_init(c);
  135. break;
  136. default:
  137. default_tuner_init(c);
  138. break;
  139. }
  140. }
  141. static char pal[] = "-";
  142. module_param_string(pal, pal, sizeof(pal), 0644);
  143. static int tuner_fixup_std(struct tuner *t)
  144. {
  145. if ((t->std & V4L2_STD_PAL) == V4L2_STD_PAL) {
  146. /* get more precise norm info from insmod option */
  147. switch (pal[0]) {
  148. case 'b':
  149. case 'B':
  150. case 'g':
  151. case 'G':
  152. tuner_dbg("insmod fixup: PAL => PAL-BG\n");
  153. t->std = V4L2_STD_PAL_BG;
  154. break;
  155. case 'i':
  156. case 'I':
  157. tuner_dbg("insmod fixup: PAL => PAL-I\n");
  158. t->std = V4L2_STD_PAL_I;
  159. break;
  160. case 'd':
  161. case 'D':
  162. case 'k':
  163. case 'K':
  164. tuner_dbg("insmod fixup: PAL => PAL-DK\n");
  165. t->std = V4L2_STD_PAL_DK;
  166. break;
  167. }
  168. }
  169. return 0;
  170. }
  171. /* ---------------------------------------------------------------------- */
  172. static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
  173. {
  174. struct tuner *t;
  175. if (this_adap > 0)
  176. return -1;
  177. this_adap++;
  178. client_template.adapter = adap;
  179. client_template.addr = addr;
  180. t = kmalloc(sizeof(struct tuner),GFP_KERNEL);
  181. if (NULL == t)
  182. return -ENOMEM;
  183. memset(t,0,sizeof(struct tuner));
  184. memcpy(&t->i2c,&client_template,sizeof(struct i2c_client));
  185. i2c_set_clientdata(&t->i2c, t);
  186. t->type = UNSET;
  187. t->radio_if2 = 10700*1000; // 10.7MHz - FM radio
  188. i2c_attach_client(&t->i2c);
  189. tuner_info("chip found @ 0x%x (%s)\n",
  190. addr << 1, adap->name);
  191. set_type(&t->i2c, t->type);
  192. return 0;
  193. }
  194. static int tuner_probe(struct i2c_adapter *adap)
  195. {
  196. if (0 != addr) {
  197. normal_i2c[0] = addr;
  198. normal_i2c_range[0] = addr;
  199. normal_i2c_range[1] = addr;
  200. }
  201. this_adap = 0;
  202. if (adap->class & I2C_CLASS_TV_ANALOG)
  203. return i2c_probe(adap, &addr_data, tuner_attach);
  204. return 0;
  205. }
  206. static int tuner_detach(struct i2c_client *client)
  207. {
  208. struct tuner *t = i2c_get_clientdata(client);
  209. i2c_detach_client(&t->i2c);
  210. kfree(t);
  211. return 0;
  212. }
  213. #define SWITCH_V4L2 if (!t->using_v4l2 && tuner_debug) \
  214. tuner_info("switching to v4l2\n"); \
  215. t->using_v4l2 = 1;
  216. #define CHECK_V4L2 if (t->using_v4l2) { if (tuner_debug) \
  217. tuner_info("ignore v4l1 call\n"); \
  218. return 0; }
  219. static int
  220. tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
  221. {
  222. struct tuner *t = i2c_get_clientdata(client);
  223. unsigned int *iarg = (int*)arg;
  224. switch (cmd) {
  225. /* --- configuration --- */
  226. case TUNER_SET_TYPE:
  227. set_type(client,*iarg);
  228. break;
  229. case AUDC_SET_RADIO:
  230. if (V4L2_TUNER_RADIO != t->mode) {
  231. set_tv_freq(client,400 * 16);
  232. t->mode = V4L2_TUNER_RADIO;
  233. }
  234. break;
  235. case AUDC_CONFIG_PINNACLE:
  236. switch (*iarg) {
  237. case 2:
  238. tuner_dbg("pinnacle pal\n");
  239. t->radio_if2 = 33300 * 1000;
  240. break;
  241. case 3:
  242. tuner_dbg("pinnacle ntsc\n");
  243. t->radio_if2 = 41300 * 1000;
  244. break;
  245. }
  246. break;
  247. /* --- v4l ioctls --- */
  248. /* take care: bttv does userspace copying, we'll get a
  249. kernel pointer here... */
  250. case VIDIOCSCHAN:
  251. {
  252. static const v4l2_std_id map[] = {
  253. [ VIDEO_MODE_PAL ] = V4L2_STD_PAL,
  254. [ VIDEO_MODE_NTSC ] = V4L2_STD_NTSC_M,
  255. [ VIDEO_MODE_SECAM ] = V4L2_STD_SECAM,
  256. [ 4 /* bttv */ ] = V4L2_STD_PAL_M,
  257. [ 5 /* bttv */ ] = V4L2_STD_PAL_N,
  258. [ 6 /* bttv */ ] = V4L2_STD_NTSC_M_JP,
  259. };
  260. struct video_channel *vc = arg;
  261. CHECK_V4L2;
  262. t->mode = V4L2_TUNER_ANALOG_TV;
  263. if (vc->norm < ARRAY_SIZE(map))
  264. t->std = map[vc->norm];
  265. tuner_fixup_std(t);
  266. if (t->freq)
  267. set_tv_freq(client,t->freq);
  268. return 0;
  269. }
  270. case VIDIOCSFREQ:
  271. {
  272. unsigned long *v = arg;
  273. CHECK_V4L2;
  274. set_freq(client,*v);
  275. return 0;
  276. }
  277. case VIDIOCGTUNER:
  278. {
  279. struct video_tuner *vt = arg;
  280. CHECK_V4L2;
  281. if (V4L2_TUNER_RADIO == t->mode && t->has_signal)
  282. vt->signal = t->has_signal(client);
  283. return 0;
  284. }
  285. case VIDIOCGAUDIO:
  286. {
  287. struct video_audio *va = arg;
  288. CHECK_V4L2;
  289. if (V4L2_TUNER_RADIO == t->mode && t->is_stereo)
  290. va->mode = t->is_stereo(client)
  291. ? VIDEO_SOUND_STEREO
  292. : VIDEO_SOUND_MONO;
  293. return 0;
  294. }
  295. case VIDIOC_S_STD:
  296. {
  297. v4l2_std_id *id = arg;
  298. SWITCH_V4L2;
  299. t->mode = V4L2_TUNER_ANALOG_TV;
  300. t->std = *id;
  301. tuner_fixup_std(t);
  302. if (t->freq)
  303. set_freq(client,t->freq);
  304. break;
  305. }
  306. case VIDIOC_S_FREQUENCY:
  307. {
  308. struct v4l2_frequency *f = arg;
  309. SWITCH_V4L2;
  310. if (V4L2_TUNER_RADIO == f->type &&
  311. V4L2_TUNER_RADIO != t->mode)
  312. set_tv_freq(client,400*16);
  313. t->mode = f->type;
  314. set_freq(client,f->frequency);
  315. break;
  316. }
  317. case VIDIOC_G_TUNER:
  318. {
  319. struct v4l2_tuner *tuner = arg;
  320. SWITCH_V4L2;
  321. if (V4L2_TUNER_RADIO == t->mode && t->has_signal)
  322. tuner->signal = t->has_signal(client);
  323. break;
  324. }
  325. default:
  326. /* nothing */
  327. break;
  328. }
  329. return 0;
  330. }
  331. static int tuner_suspend(struct device * dev, pm_message_t state, u32 level)
  332. {
  333. struct i2c_client *c = container_of(dev, struct i2c_client, dev);
  334. struct tuner *t = i2c_get_clientdata(c);
  335. tuner_dbg("suspend\n");
  336. /* FIXME: power down ??? */
  337. return 0;
  338. }
  339. static int tuner_resume(struct device * dev, u32 level)
  340. {
  341. struct i2c_client *c = container_of(dev, struct i2c_client, dev);
  342. struct tuner *t = i2c_get_clientdata(c);
  343. tuner_dbg("resume\n");
  344. if (t->freq)
  345. set_freq(c,t->freq);
  346. return 0;
  347. }
  348. /* ----------------------------------------------------------------------- */
  349. static struct i2c_driver driver = {
  350. .owner = THIS_MODULE,
  351. .name = "tuner",
  352. .id = I2C_DRIVERID_TUNER,
  353. .flags = I2C_DF_NOTIFY,
  354. .attach_adapter = tuner_probe,
  355. .detach_client = tuner_detach,
  356. .command = tuner_command,
  357. .driver = {
  358. .suspend = tuner_suspend,
  359. .resume = tuner_resume,
  360. },
  361. };
  362. static struct i2c_client client_template =
  363. {
  364. I2C_DEVNAME("(tuner unset)"),
  365. .flags = I2C_CLIENT_ALLOW_USE,
  366. .driver = &driver,
  367. };
  368. static int __init tuner_init_module(void)
  369. {
  370. return i2c_add_driver(&driver);
  371. }
  372. static void __exit tuner_cleanup_module(void)
  373. {
  374. i2c_del_driver(&driver);
  375. }
  376. module_init(tuner_init_module);
  377. module_exit(tuner_cleanup_module);
  378. /*
  379. * Overrides for Emacs so that we follow Linus's tabbing style.
  380. * ---------------------------------------------------------------------------
  381. * Local variables:
  382. * c-basic-offset: 8
  383. * End:
  384. */