tda9887.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825
  1. #include <linux/module.h>
  2. #include <linux/moduleparam.h>
  3. #include <linux/kernel.h>
  4. #include <linux/i2c.h>
  5. #include <linux/types.h>
  6. #include <linux/videodev.h>
  7. #include <linux/init.h>
  8. #include <linux/errno.h>
  9. #include <linux/slab.h>
  10. #include <linux/delay.h>
  11. #include <media/audiochip.h>
  12. #include <media/tuner.h>
  13. /* Chips:
  14. TDA9885 (PAL, NTSC)
  15. TDA9886 (PAL, SECAM, NTSC)
  16. TDA9887 (PAL, SECAM, NTSC, FM Radio)
  17. found on:
  18. - Pinnacle PCTV (Jul.2002 Version with MT2032, bttv)
  19. TDA9887 (world), TDA9885 (USA)
  20. Note: OP2 of tda988x must be set to 1, else MT2032 is disabled!
  21. - KNC One TV-Station RDS (saa7134)
  22. - Hauppauge PVR-150/500 (possibly more)
  23. */
  24. /* Addresses to scan */
  25. static unsigned short normal_i2c[] = {
  26. 0x84 >>1,
  27. 0x86 >>1,
  28. 0x96 >>1,
  29. I2C_CLIENT_END,
  30. };
  31. I2C_CLIENT_INSMOD;
  32. /* insmod options */
  33. static unsigned int debug = 0;
  34. module_param(debug, int, 0644);
  35. MODULE_LICENSE("GPL");
  36. /* ---------------------------------------------------------------------- */
  37. #define UNSET (-1U)
  38. #define tda9887_info(fmt, arg...) do {\
  39. printk(KERN_INFO "%s %d-%04x: " fmt, t->client.name, \
  40. i2c_adapter_id(t->client.adapter), t->client.addr , ##arg); } while (0)
  41. #define tda9887_dbg(fmt, arg...) do {\
  42. if (debug) \
  43. printk(KERN_INFO "%s %d-%04x: " fmt, t->client.name, \
  44. i2c_adapter_id(t->client.adapter), t->client.addr , ##arg); } while (0)
  45. struct tda9887 {
  46. struct i2c_client client;
  47. v4l2_std_id std;
  48. enum tuner_mode mode;
  49. unsigned int config;
  50. unsigned int using_v4l2;
  51. unsigned int radio_mode;
  52. unsigned char data[4];
  53. };
  54. struct tvnorm {
  55. v4l2_std_id std;
  56. char *name;
  57. unsigned char b;
  58. unsigned char c;
  59. unsigned char e;
  60. };
  61. static struct i2c_driver driver;
  62. static struct i2c_client client_template;
  63. /* ---------------------------------------------------------------------- */
  64. //
  65. // TDA defines
  66. //
  67. //// first reg (b)
  68. #define cVideoTrapBypassOFF 0x00 // bit b0
  69. #define cVideoTrapBypassON 0x01 // bit b0
  70. #define cAutoMuteFmInactive 0x00 // bit b1
  71. #define cAutoMuteFmActive 0x02 // bit b1
  72. #define cIntercarrier 0x00 // bit b2
  73. #define cQSS 0x04 // bit b2
  74. #define cPositiveAmTV 0x00 // bit b3:4
  75. #define cFmRadio 0x08 // bit b3:4
  76. #define cNegativeFmTV 0x10 // bit b3:4
  77. #define cForcedMuteAudioON 0x20 // bit b5
  78. #define cForcedMuteAudioOFF 0x00 // bit b5
  79. #define cOutputPort1Active 0x00 // bit b6
  80. #define cOutputPort1Inactive 0x40 // bit b6
  81. #define cOutputPort2Active 0x00 // bit b7
  82. #define cOutputPort2Inactive 0x80 // bit b7
  83. //// second reg (c)
  84. #define cDeemphasisOFF 0x00 // bit c5
  85. #define cDeemphasisON 0x20 // bit c5
  86. #define cDeemphasis75 0x00 // bit c6
  87. #define cDeemphasis50 0x40 // bit c6
  88. #define cAudioGain0 0x00 // bit c7
  89. #define cAudioGain6 0x80 // bit c7
  90. //// third reg (e)
  91. #define cAudioIF_4_5 0x00 // bit e0:1
  92. #define cAudioIF_5_5 0x01 // bit e0:1
  93. #define cAudioIF_6_0 0x02 // bit e0:1
  94. #define cAudioIF_6_5 0x03 // bit e0:1
  95. #define cVideoIF_58_75 0x00 // bit e2:4
  96. #define cVideoIF_45_75 0x04 // bit e2:4
  97. #define cVideoIF_38_90 0x08 // bit e2:4
  98. #define cVideoIF_38_00 0x0C // bit e2:4
  99. #define cVideoIF_33_90 0x10 // bit e2:4
  100. #define cVideoIF_33_40 0x14 // bit e2:4
  101. #define cRadioIF_45_75 0x18 // bit e2:4
  102. #define cRadioIF_38_90 0x1C // bit e2:4
  103. #define cTunerGainNormal 0x00 // bit e5
  104. #define cTunerGainLow 0x20 // bit e5
  105. #define cGating_18 0x00 // bit e6
  106. #define cGating_36 0x40 // bit e6
  107. #define cAgcOutON 0x80 // bit e7
  108. #define cAgcOutOFF 0x00 // bit e7
  109. /* ---------------------------------------------------------------------- */
  110. static struct tvnorm tvnorms[] = {
  111. {
  112. .std = V4L2_STD_PAL_BG,
  113. .name = "PAL-BG",
  114. .b = ( cNegativeFmTV |
  115. cQSS ),
  116. .c = ( cDeemphasisON |
  117. cDeemphasis50 ),
  118. .e = ( cAudioIF_5_5 |
  119. cVideoIF_38_90 ),
  120. },{
  121. .std = V4L2_STD_PAL_I,
  122. .name = "PAL-I",
  123. .b = ( cNegativeFmTV |
  124. cQSS ),
  125. .c = ( cDeemphasisON |
  126. cDeemphasis50 ),
  127. .e = ( cAudioIF_6_0 |
  128. cVideoIF_38_90 ),
  129. },{
  130. .std = V4L2_STD_PAL_DK,
  131. .name = "PAL-DK",
  132. .b = ( cNegativeFmTV |
  133. cQSS ),
  134. .c = ( cDeemphasisON |
  135. cDeemphasis50 ),
  136. .e = ( cAudioIF_6_5 |
  137. cVideoIF_38_00 ),
  138. },{
  139. .std = V4L2_STD_PAL_M | V4L2_STD_PAL_N,
  140. .name = "PAL-M/N",
  141. .b = ( cNegativeFmTV |
  142. cQSS ),
  143. .c = ( cDeemphasisON |
  144. cDeemphasis75 ),
  145. .e = ( cAudioIF_4_5 |
  146. cVideoIF_45_75 ),
  147. },{
  148. .std = V4L2_STD_SECAM_L,
  149. .name = "SECAM-L",
  150. .b = ( cPositiveAmTV |
  151. cQSS ),
  152. .e = ( cGating_36 |
  153. cAudioIF_6_5 |
  154. cVideoIF_38_90 ),
  155. },{
  156. .std = V4L2_STD_SECAM_LC,
  157. .name = "SECAM-L'",
  158. .b = ( cOutputPort2Inactive |
  159. cPositiveAmTV |
  160. cQSS ),
  161. .e = ( cGating_36 |
  162. cAudioIF_6_5 |
  163. cVideoIF_33_90 ),
  164. },{
  165. .std = V4L2_STD_SECAM_DK,
  166. .name = "SECAM-DK",
  167. .b = ( cNegativeFmTV |
  168. cQSS ),
  169. .c = ( cDeemphasisON |
  170. cDeemphasis50 ),
  171. .e = ( cAudioIF_6_5 |
  172. cVideoIF_38_00 ),
  173. },{
  174. .std = V4L2_STD_NTSC_M,
  175. .name = "NTSC-M",
  176. .b = ( cNegativeFmTV |
  177. cQSS ),
  178. .c = ( cDeemphasisON |
  179. cDeemphasis75 ),
  180. .e = ( cGating_36 |
  181. cAudioIF_4_5 |
  182. cVideoIF_45_75 ),
  183. },{
  184. .std = V4L2_STD_NTSC_M_JP,
  185. .name = "NTSC-JP",
  186. .b = ( cNegativeFmTV |
  187. cQSS ),
  188. .c = ( cDeemphasisON |
  189. cDeemphasis50 ),
  190. .e = ( cGating_36 |
  191. cAudioIF_4_5 |
  192. cVideoIF_58_75 ),
  193. }
  194. };
  195. static struct tvnorm radio_stereo = {
  196. .name = "Radio Stereo",
  197. .b = ( cFmRadio |
  198. cQSS ),
  199. .c = ( cDeemphasisOFF |
  200. cAudioGain6 ),
  201. .e = ( cAudioIF_5_5 |
  202. cRadioIF_38_90 ),
  203. };
  204. static struct tvnorm radio_mono = {
  205. .name = "Radio Mono",
  206. .b = ( cFmRadio |
  207. cQSS ),
  208. .c = ( cDeemphasisON |
  209. cDeemphasis50),
  210. .e = ( cAudioIF_5_5 |
  211. cRadioIF_38_90 ),
  212. };
  213. /* ---------------------------------------------------------------------- */
  214. static void dump_read_message(struct tda9887 *t, unsigned char *buf)
  215. {
  216. static char *afc[16] = {
  217. "- 12.5 kHz",
  218. "- 37.5 kHz",
  219. "- 62.5 kHz",
  220. "- 87.5 kHz",
  221. "-112.5 kHz",
  222. "-137.5 kHz",
  223. "-162.5 kHz",
  224. "-187.5 kHz [min]",
  225. "+187.5 kHz [max]",
  226. "+162.5 kHz",
  227. "+137.5 kHz",
  228. "+112.5 kHz",
  229. "+ 87.5 kHz",
  230. "+ 62.5 kHz",
  231. "+ 37.5 kHz",
  232. "+ 12.5 kHz",
  233. };
  234. tda9887_info("read: 0x%2x\n", buf[0]);
  235. tda9887_info(" after power on : %s\n", (buf[0] & 0x01) ? "yes" : "no");
  236. tda9887_info(" afc : %s\n", afc[(buf[0] >> 1) & 0x0f]);
  237. tda9887_info(" fmif level : %s\n", (buf[0] & 0x20) ? "high" : "low");
  238. tda9887_info(" afc window : %s\n", (buf[0] & 0x40) ? "in" : "out");
  239. tda9887_info(" vfi level : %s\n", (buf[0] & 0x80) ? "high" : "low");
  240. }
  241. static void dump_write_message(struct tda9887 *t, unsigned char *buf)
  242. {
  243. static char *sound[4] = {
  244. "AM/TV",
  245. "FM/radio",
  246. "FM/TV",
  247. "FM/radio"
  248. };
  249. static char *adjust[32] = {
  250. "-16", "-15", "-14", "-13", "-12", "-11", "-10", "-9",
  251. "-8", "-7", "-6", "-5", "-4", "-3", "-2", "-1",
  252. "0", "+1", "+2", "+3", "+4", "+5", "+6", "+7",
  253. "+8", "+9", "+10", "+11", "+12", "+13", "+14", "+15"
  254. };
  255. static char *deemph[4] = {
  256. "no", "no", "75", "50"
  257. };
  258. static char *carrier[4] = {
  259. "4.5 MHz",
  260. "5.5 MHz",
  261. "6.0 MHz",
  262. "6.5 MHz / AM"
  263. };
  264. static char *vif[8] = {
  265. "58.75 MHz",
  266. "45.75 MHz",
  267. "38.9 MHz",
  268. "38.0 MHz",
  269. "33.9 MHz",
  270. "33.4 MHz",
  271. "45.75 MHz + pin13",
  272. "38.9 MHz + pin13",
  273. };
  274. static char *rif[4] = {
  275. "44 MHz",
  276. "52 MHz",
  277. "52 MHz",
  278. "44 MHz",
  279. };
  280. tda9887_info("write: byte B 0x%02x\n",buf[1]);
  281. tda9887_info(" B0 video mode : %s\n",
  282. (buf[1] & 0x01) ? "video trap" : "sound trap");
  283. tda9887_info(" B1 auto mute fm : %s\n",
  284. (buf[1] & 0x02) ? "yes" : "no");
  285. tda9887_info(" B2 carrier mode : %s\n",
  286. (buf[1] & 0x04) ? "QSS" : "Intercarrier");
  287. tda9887_info(" B3-4 tv sound/radio : %s\n",
  288. sound[(buf[1] & 0x18) >> 3]);
  289. tda9887_info(" B5 force mute audio: %s\n",
  290. (buf[1] & 0x20) ? "yes" : "no");
  291. tda9887_info(" B6 output port 1 : %s\n",
  292. (buf[1] & 0x40) ? "high (inactive)" : "low (active)");
  293. tda9887_info(" B7 output port 2 : %s\n",
  294. (buf[1] & 0x80) ? "high (inactive)" : "low (active)");
  295. tda9887_info("write: byte C 0x%02x\n",buf[2]);
  296. tda9887_info(" C0-4 top adjustment : %s dB\n", adjust[buf[2] & 0x1f]);
  297. tda9887_info(" C5-6 de-emphasis : %s\n", deemph[(buf[2] & 0x60) >> 5]);
  298. tda9887_info(" C7 audio gain : %s\n",
  299. (buf[2] & 0x80) ? "-6" : "0");
  300. tda9887_info("write: byte E 0x%02x\n",buf[3]);
  301. tda9887_info(" E0-1 sound carrier : %s\n",
  302. carrier[(buf[3] & 0x03)]);
  303. tda9887_info(" E6 l pll gating : %s\n",
  304. (buf[3] & 0x40) ? "36" : "13");
  305. if (buf[1] & 0x08) {
  306. /* radio */
  307. tda9887_info(" E2-4 video if : %s\n",
  308. rif[(buf[3] & 0x0c) >> 2]);
  309. tda9887_info(" E7 vif agc output : %s\n",
  310. (buf[3] & 0x80)
  311. ? ((buf[3] & 0x10) ? "fm-agc radio" : "sif-agc radio")
  312. : "fm radio carrier afc");
  313. } else {
  314. /* video */
  315. tda9887_info(" E2-4 video if : %s\n",
  316. vif[(buf[3] & 0x1c) >> 2]);
  317. tda9887_info(" E5 tuner gain : %s\n",
  318. (buf[3] & 0x80)
  319. ? ((buf[3] & 0x20) ? "external" : "normal")
  320. : ((buf[3] & 0x20) ? "minimum" : "normal"));
  321. tda9887_info(" E7 vif agc output : %s\n",
  322. (buf[3] & 0x80)
  323. ? ((buf[3] & 0x20)
  324. ? "pin3 port, pin22 vif agc out"
  325. : "pin22 port, pin3 vif acg ext in")
  326. : "pin3+pin22 port");
  327. }
  328. tda9887_info("--\n");
  329. }
  330. /* ---------------------------------------------------------------------- */
  331. static int tda9887_set_tvnorm(struct tda9887 *t, char *buf)
  332. {
  333. struct tvnorm *norm = NULL;
  334. int i;
  335. if (t->mode == T_RADIO) {
  336. if (t->radio_mode == V4L2_TUNER_MODE_MONO)
  337. norm = &radio_mono;
  338. else
  339. norm = &radio_stereo;
  340. } else {
  341. for (i = 0; i < ARRAY_SIZE(tvnorms); i++) {
  342. if (tvnorms[i].std & t->std) {
  343. norm = tvnorms+i;
  344. break;
  345. }
  346. }
  347. }
  348. if (NULL == norm) {
  349. tda9887_dbg("Unsupported tvnorm entry - audio muted\n");
  350. return -1;
  351. }
  352. tda9887_dbg("configure for: %s\n",norm->name);
  353. buf[1] = norm->b;
  354. buf[2] = norm->c;
  355. buf[3] = norm->e;
  356. return 0;
  357. }
  358. static unsigned int port1 = UNSET;
  359. static unsigned int port2 = UNSET;
  360. static unsigned int qss = UNSET;
  361. static unsigned int adjust = 0x10;
  362. module_param(port1, int, 0644);
  363. module_param(port2, int, 0644);
  364. module_param(qss, int, 0644);
  365. module_param(adjust, int, 0644);
  366. static int tda9887_set_insmod(struct tda9887 *t, char *buf)
  367. {
  368. if (UNSET != port1) {
  369. if (port1)
  370. buf[1] |= cOutputPort1Inactive;
  371. else
  372. buf[1] &= ~cOutputPort1Inactive;
  373. }
  374. if (UNSET != port2) {
  375. if (port2)
  376. buf[1] |= cOutputPort2Inactive;
  377. else
  378. buf[1] &= ~cOutputPort2Inactive;
  379. }
  380. if (UNSET != qss) {
  381. if (qss)
  382. buf[1] |= cQSS;
  383. else
  384. buf[1] &= ~cQSS;
  385. }
  386. if (adjust >= 0x00 && adjust < 0x20)
  387. buf[2] |= adjust;
  388. return 0;
  389. }
  390. static int tda9887_set_config(struct tda9887 *t, char *buf)
  391. {
  392. if (t->config & TDA9887_PORT1_ACTIVE)
  393. buf[1] &= ~cOutputPort1Inactive;
  394. if (t->config & TDA9887_PORT1_INACTIVE)
  395. buf[1] |= cOutputPort1Inactive;
  396. if (t->config & TDA9887_PORT2_ACTIVE)
  397. buf[1] &= ~cOutputPort2Inactive;
  398. if (t->config & TDA9887_PORT2_INACTIVE)
  399. buf[1] |= cOutputPort2Inactive;
  400. if (t->config & TDA9887_QSS)
  401. buf[1] |= cQSS;
  402. if (t->config & TDA9887_INTERCARRIER)
  403. buf[1] &= ~cQSS;
  404. if (t->config & TDA9887_AUTOMUTE)
  405. buf[1] |= cAutoMuteFmActive;
  406. if (t->config & TDA9887_DEEMPHASIS_MASK) {
  407. buf[2] &= ~0x60;
  408. switch (t->config & TDA9887_DEEMPHASIS_MASK) {
  409. case TDA9887_DEEMPHASIS_NONE:
  410. buf[2] |= cDeemphasisOFF;
  411. break;
  412. case TDA9887_DEEMPHASIS_50:
  413. buf[2] |= cDeemphasisON | cDeemphasis50;
  414. break;
  415. case TDA9887_DEEMPHASIS_75:
  416. buf[2] |= cDeemphasisON | cDeemphasis75;
  417. break;
  418. }
  419. }
  420. if ((t->config & TDA9887_INTERCARRIER_NTSC) && (t->std & V4L2_STD_NTSC))
  421. buf[1] &= ~cQSS;
  422. return 0;
  423. }
  424. /* ---------------------------------------------------------------------- */
  425. static char pal[] = "-";
  426. module_param_string(pal, pal, sizeof(pal), 0644);
  427. static char secam[] = "-";
  428. module_param_string(secam, secam, sizeof(secam), 0644);
  429. static int tda9887_fixup_std(struct tda9887 *t)
  430. {
  431. /* get more precise norm info from insmod option */
  432. if ((t->std & V4L2_STD_PAL) == V4L2_STD_PAL) {
  433. switch (pal[0]) {
  434. case 'b':
  435. case 'B':
  436. case 'g':
  437. case 'G':
  438. tda9887_dbg("insmod fixup: PAL => PAL-BG\n");
  439. t->std = V4L2_STD_PAL_BG;
  440. break;
  441. case 'i':
  442. case 'I':
  443. tda9887_dbg("insmod fixup: PAL => PAL-I\n");
  444. t->std = V4L2_STD_PAL_I;
  445. break;
  446. case 'd':
  447. case 'D':
  448. case 'k':
  449. case 'K':
  450. tda9887_dbg("insmod fixup: PAL => PAL-DK\n");
  451. t->std = V4L2_STD_PAL_DK;
  452. break;
  453. case '-':
  454. /* default parameter, do nothing */
  455. break;
  456. default:
  457. tda9887_info("pal= argument not recognised\n");
  458. break;
  459. }
  460. }
  461. if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
  462. switch (secam[0]) {
  463. case 'd':
  464. case 'D':
  465. case 'k':
  466. case 'K':
  467. tda9887_dbg("insmod fixup: SECAM => SECAM-DK\n");
  468. t->std = V4L2_STD_SECAM_DK;
  469. break;
  470. case 'l':
  471. case 'L':
  472. tda9887_dbg("insmod fixup: SECAM => SECAM-L\n");
  473. t->std = V4L2_STD_SECAM_L;
  474. break;
  475. case '-':
  476. /* default parameter, do nothing */
  477. break;
  478. default:
  479. tda9887_info("secam= argument not recognised\n");
  480. break;
  481. }
  482. }
  483. return 0;
  484. }
  485. static int tda9887_status(struct tda9887 *t)
  486. {
  487. unsigned char buf[1];
  488. int rc;
  489. memset(buf,0,sizeof(buf));
  490. if (1 != (rc = i2c_master_recv(&t->client,buf,1)))
  491. tda9887_info("i2c i/o error: rc == %d (should be 1)\n",rc);
  492. dump_read_message(t, buf);
  493. return 0;
  494. }
  495. static int tda9887_configure(struct tda9887 *t)
  496. {
  497. int rc;
  498. memset(t->data,0,sizeof(t->data));
  499. tda9887_set_tvnorm(t,t->data);
  500. t->data[1] |= cOutputPort1Inactive;
  501. t->data[1] |= cOutputPort2Inactive;
  502. tda9887_set_config(t,t->data);
  503. tda9887_set_insmod(t,t->data);
  504. if (t->mode == T_STANDBY) {
  505. t->data[1] |= cForcedMuteAudioON;
  506. }
  507. tda9887_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n",
  508. t->data[1],t->data[2],t->data[3]);
  509. if (debug > 1)
  510. dump_write_message(t, t->data);
  511. if (4 != (rc = i2c_master_send(&t->client,t->data,4)))
  512. tda9887_info("i2c i/o error: rc == %d (should be 4)\n",rc);
  513. if (debug > 2) {
  514. msleep_interruptible(1000);
  515. tda9887_status(t);
  516. }
  517. return 0;
  518. }
  519. /* ---------------------------------------------------------------------- */
  520. static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind)
  521. {
  522. struct tda9887 *t;
  523. client_template.adapter = adap;
  524. client_template.addr = addr;
  525. if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL)))
  526. return -ENOMEM;
  527. memset(t,0,sizeof(*t));
  528. t->client = client_template;
  529. t->std = 0;
  530. t->radio_mode = V4L2_TUNER_MODE_STEREO;
  531. tda9887_info("chip found @ 0x%x (%s)\n", addr<<1, adap->name);
  532. i2c_set_clientdata(&t->client, t);
  533. i2c_attach_client(&t->client);
  534. return 0;
  535. }
  536. static int tda9887_probe(struct i2c_adapter *adap)
  537. {
  538. #ifdef I2C_CLASS_TV_ANALOG
  539. if (adap->class & I2C_CLASS_TV_ANALOG)
  540. return i2c_probe(adap, &addr_data, tda9887_attach);
  541. #else
  542. switch (adap->id) {
  543. case I2C_HW_B_BT848:
  544. case I2C_HW_B_RIVA:
  545. case I2C_HW_SAA7134:
  546. return i2c_probe(adap, &addr_data, tda9887_attach);
  547. break;
  548. }
  549. #endif
  550. return 0;
  551. }
  552. static int tda9887_detach(struct i2c_client *client)
  553. {
  554. struct tda9887 *t = i2c_get_clientdata(client);
  555. i2c_detach_client(client);
  556. kfree(t);
  557. return 0;
  558. }
  559. #define SWITCH_V4L2 if (!t->using_v4l2 && debug) \
  560. tda9887_info("switching to v4l2\n"); \
  561. t->using_v4l2 = 1;
  562. #define CHECK_V4L2 if (t->using_v4l2) { if (debug) \
  563. tda9887_info("ignore v4l1 call\n"); \
  564. return 0; }
  565. static int
  566. tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
  567. {
  568. struct tda9887 *t = i2c_get_clientdata(client);
  569. switch (cmd) {
  570. /* --- configuration --- */
  571. case AUDC_SET_RADIO:
  572. {
  573. t->mode = T_RADIO;
  574. tda9887_configure(t);
  575. break;
  576. }
  577. case TUNER_SET_STANDBY:
  578. {
  579. t->mode = T_STANDBY;
  580. tda9887_configure(t);
  581. break;
  582. }
  583. case TDA9887_SET_CONFIG:
  584. {
  585. int *i = arg;
  586. t->config = *i;
  587. tda9887_configure(t);
  588. break;
  589. }
  590. /* --- v4l ioctls --- */
  591. /* take care: bttv does userspace copying, we'll get a
  592. kernel pointer here... */
  593. case VIDIOCSCHAN:
  594. {
  595. static const v4l2_std_id map[] = {
  596. [ VIDEO_MODE_PAL ] = V4L2_STD_PAL,
  597. [ VIDEO_MODE_NTSC ] = V4L2_STD_NTSC_M,
  598. [ VIDEO_MODE_SECAM ] = V4L2_STD_SECAM,
  599. [ 4 /* bttv */ ] = V4L2_STD_PAL_M,
  600. [ 5 /* bttv */ ] = V4L2_STD_PAL_N,
  601. [ 6 /* bttv */ ] = V4L2_STD_NTSC_M_JP,
  602. };
  603. struct video_channel *vc = arg;
  604. CHECK_V4L2;
  605. t->mode = T_ANALOG_TV;
  606. if (vc->norm < ARRAY_SIZE(map))
  607. t->std = map[vc->norm];
  608. tda9887_fixup_std(t);
  609. tda9887_configure(t);
  610. break;
  611. }
  612. case VIDIOC_S_STD:
  613. {
  614. v4l2_std_id *id = arg;
  615. SWITCH_V4L2;
  616. t->mode = T_ANALOG_TV;
  617. t->std = *id;
  618. tda9887_fixup_std(t);
  619. tda9887_configure(t);
  620. break;
  621. }
  622. case VIDIOC_S_FREQUENCY:
  623. {
  624. struct v4l2_frequency *f = arg;
  625. SWITCH_V4L2;
  626. if (V4L2_TUNER_ANALOG_TV == f->type) {
  627. if (t->mode == T_ANALOG_TV)
  628. return 0;
  629. t->mode = T_ANALOG_TV;
  630. }
  631. if (V4L2_TUNER_RADIO == f->type) {
  632. if (t->mode == T_RADIO)
  633. return 0;
  634. t->mode = T_RADIO;
  635. }
  636. tda9887_configure(t);
  637. break;
  638. }
  639. case VIDIOC_G_TUNER:
  640. {
  641. static int AFC_BITS_2_kHz[] = {
  642. -12500, -37500, -62500, -97500,
  643. -112500, -137500, -162500, -187500,
  644. 187500, 162500, 137500, 112500,
  645. 97500 , 62500, 37500 , 12500
  646. };
  647. struct v4l2_tuner* tuner = arg;
  648. if (t->mode == T_RADIO) {
  649. __u8 reg = 0;
  650. tuner->afc=0;
  651. if (1 == i2c_master_recv(&t->client,&reg,1))
  652. tuner->afc = AFC_BITS_2_kHz[(reg>>1)&0x0f];
  653. }
  654. break;
  655. }
  656. case VIDIOC_S_TUNER:
  657. {
  658. struct v4l2_tuner* tuner = arg;
  659. if (t->mode == T_RADIO) {
  660. t->radio_mode = tuner->audmode;
  661. tda9887_configure (t);
  662. }
  663. break;
  664. }
  665. case VIDIOC_LOG_STATUS:
  666. {
  667. tda9887_info("Data bytes: b=0x%02x c=0x%02x e=0x%02x\n", t->data[1], t->data[2], t->data[3]);
  668. break;
  669. }
  670. default:
  671. /* nothing */
  672. break;
  673. }
  674. return 0;
  675. }
  676. static int tda9887_suspend(struct device * dev, pm_message_t state)
  677. {
  678. struct i2c_client *c = container_of(dev, struct i2c_client, dev);
  679. struct tda9887 *t = i2c_get_clientdata(c);
  680. tda9887_dbg("suspend\n");
  681. return 0;
  682. }
  683. static int tda9887_resume(struct device * dev)
  684. {
  685. struct i2c_client *c = container_of(dev, struct i2c_client, dev);
  686. struct tda9887 *t = i2c_get_clientdata(c);
  687. tda9887_dbg("resume\n");
  688. tda9887_configure(t);
  689. return 0;
  690. }
  691. /* ----------------------------------------------------------------------- */
  692. static struct i2c_driver driver = {
  693. .id = -1, /* FIXME */
  694. .attach_adapter = tda9887_probe,
  695. .detach_client = tda9887_detach,
  696. .command = tda9887_command,
  697. .driver = {
  698. .name = "i2c tda9887 driver",
  699. .suspend = tda9887_suspend,
  700. .resume = tda9887_resume,
  701. },
  702. };
  703. static struct i2c_client client_template =
  704. {
  705. .name = "tda9887",
  706. .driver = &driver,
  707. };
  708. static int __init tda9887_init_module(void)
  709. {
  710. return i2c_add_driver(&driver);
  711. }
  712. static void __exit tda9887_cleanup_module(void)
  713. {
  714. i2c_del_driver(&driver);
  715. }
  716. module_init(tda9887_init_module);
  717. module_exit(tda9887_cleanup_module);
  718. /*
  719. * Overrides for Emacs so that we follow Linus's tabbing style.
  720. * ---------------------------------------------------------------------------
  721. * Local variables:
  722. * c-basic-offset: 8
  723. * End:
  724. */