saa7191.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807
  1. /*
  2. * saa7191.c - Philips SAA7191 video decoder driver
  3. *
  4. * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
  5. * Copyright (C) 2004,2005 Mikael Nousiainen <tmnousia@cc.hut.fi>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License version 2 as
  9. * published by the Free Software Foundation.
  10. */
  11. #include <linux/delay.h>
  12. #include <linux/errno.h>
  13. #include <linux/fs.h>
  14. #include <linux/init.h>
  15. #include <linux/kernel.h>
  16. #include <linux/major.h>
  17. #include <linux/module.h>
  18. #include <linux/mm.h>
  19. #include <linux/slab.h>
  20. #include <linux/videodev.h>
  21. #include <linux/video_decoder.h>
  22. #include <linux/i2c.h>
  23. #include "saa7191.h"
  24. #define SAA7191_MODULE_VERSION "0.0.5"
  25. MODULE_DESCRIPTION("Philips SAA7191 video decoder driver");
  26. MODULE_VERSION(SAA7191_MODULE_VERSION);
  27. MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
  28. MODULE_LICENSE("GPL");
  29. // #define SAA7191_DEBUG
  30. #ifdef SAA7191_DEBUG
  31. #define dprintk(x...) printk("SAA7191: " x);
  32. #else
  33. #define dprintk(x...)
  34. #endif
  35. #define SAA7191_SYNC_COUNT 30
  36. #define SAA7191_SYNC_DELAY 100 /* milliseconds */
  37. struct saa7191 {
  38. struct i2c_client *client;
  39. /* the register values are stored here as the actual
  40. * I2C-registers are write-only */
  41. u8 reg[25];
  42. int input;
  43. int norm;
  44. };
  45. static struct i2c_driver i2c_driver_saa7191;
  46. static const u8 initseq[] = {
  47. 0, /* Subaddress */
  48. 0x50, /* (0x50) SAA7191_REG_IDEL */
  49. /* 50 Hz signal timing */
  50. 0x30, /* (0x30) SAA7191_REG_HSYB */
  51. 0x00, /* (0x00) SAA7191_REG_HSYS */
  52. 0xe8, /* (0xe8) SAA7191_REG_HCLB */
  53. 0xb6, /* (0xb6) SAA7191_REG_HCLS */
  54. 0xf4, /* (0xf4) SAA7191_REG_HPHI */
  55. /* control */
  56. SAA7191_LUMA_APER_1, /* (0x01) SAA7191_REG_LUMA - CVBS mode */
  57. 0x00, /* (0x00) SAA7191_REG_HUEC */
  58. 0xf8, /* (0xf8) SAA7191_REG_CKTQ */
  59. 0xf8, /* (0xf8) SAA7191_REG_CKTS */
  60. 0x90, /* (0x90) SAA7191_REG_PLSE */
  61. 0x90, /* (0x90) SAA7191_REG_SESE */
  62. 0x00, /* (0x00) SAA7191_REG_GAIN */
  63. SAA7191_STDC_NFEN | SAA7191_STDC_HRMV, /* (0x0c) SAA7191_REG_STDC
  64. * - not SECAM,
  65. * slow time constant */
  66. SAA7191_IOCK_OEDC | SAA7191_IOCK_OEHS | SAA7191_IOCK_OEVS
  67. | SAA7191_IOCK_OEDY, /* (0x78) SAA7191_REG_IOCK
  68. * - chroma from CVBS, GPSW1 & 2 off */
  69. SAA7191_CTL3_AUFD | SAA7191_CTL3_SCEN | SAA7191_CTL3_OFTS
  70. | SAA7191_CTL3_YDEL0, /* (0x99) SAA7191_REG_CTL3
  71. * - automatic field detection */
  72. 0x00, /* (0x00) SAA7191_REG_CTL4 */
  73. 0x2c, /* (0x2c) SAA7191_REG_CHCV - PAL nominal value */
  74. 0x00, /* unused */
  75. 0x00, /* unused */
  76. /* 60 Hz signal timing */
  77. 0x34, /* (0x34) SAA7191_REG_HS6B */
  78. 0x0a, /* (0x0a) SAA7191_REG_HS6S */
  79. 0xf4, /* (0xf4) SAA7191_REG_HC6B */
  80. 0xce, /* (0xce) SAA7191_REG_HC6S */
  81. 0xf4, /* (0xf4) SAA7191_REG_HP6I */
  82. };
  83. /* SAA7191 register handling */
  84. static u8 saa7191_read_reg(struct i2c_client *client,
  85. u8 reg)
  86. {
  87. return ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg];
  88. }
  89. static int saa7191_read_status(struct i2c_client *client,
  90. u8 *value)
  91. {
  92. int ret;
  93. ret = i2c_master_recv(client, value, 1);
  94. if (ret < 0) {
  95. printk(KERN_ERR "SAA7191: saa7191_read_status(): read failed\n");
  96. return ret;
  97. }
  98. return 0;
  99. }
  100. static int saa7191_write_reg(struct i2c_client *client, u8 reg,
  101. u8 value)
  102. {
  103. ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg] = value;
  104. return i2c_smbus_write_byte_data(client, reg, value);
  105. }
  106. /* the first byte of data must be the first subaddress number (register) */
  107. static int saa7191_write_block(struct i2c_client *client,
  108. u8 length, const u8 *data)
  109. {
  110. int i;
  111. int ret;
  112. struct saa7191 *decoder = (struct saa7191 *)i2c_get_clientdata(client);
  113. for (i = 0; i < (length - 1); i++) {
  114. decoder->reg[data[0] + i] = data[i + 1];
  115. }
  116. ret = i2c_master_send(client, data, length);
  117. if (ret < 0) {
  118. printk(KERN_ERR "SAA7191: saa7191_write_block(): "
  119. "write failed\n");
  120. return ret;
  121. }
  122. return 0;
  123. }
  124. /* Helper functions */
  125. static int saa7191_set_input(struct i2c_client *client, int input)
  126. {
  127. struct saa7191 *decoder = i2c_get_clientdata(client);
  128. u8 luma = saa7191_read_reg(client, SAA7191_REG_LUMA);
  129. u8 iock = saa7191_read_reg(client, SAA7191_REG_IOCK);
  130. int err;
  131. switch (input) {
  132. case SAA7191_INPUT_COMPOSITE: /* Set Composite input */
  133. iock &= ~(SAA7191_IOCK_CHRS | SAA7191_IOCK_GPSW1
  134. | SAA7191_IOCK_GPSW2);
  135. /* Chrominance trap active */
  136. luma &= ~SAA7191_LUMA_BYPS;
  137. break;
  138. case SAA7191_INPUT_SVIDEO: /* Set S-Video input */
  139. iock |= SAA7191_IOCK_CHRS | SAA7191_IOCK_GPSW2;
  140. /* Chrominance trap bypassed */
  141. luma |= SAA7191_LUMA_BYPS;
  142. break;
  143. default:
  144. return -EINVAL;
  145. }
  146. err = saa7191_write_reg(client, SAA7191_REG_LUMA, luma);
  147. if (err)
  148. return -EIO;
  149. err = saa7191_write_reg(client, SAA7191_REG_IOCK, iock);
  150. if (err)
  151. return -EIO;
  152. decoder->input = input;
  153. return 0;
  154. }
  155. static int saa7191_set_norm(struct i2c_client *client, int norm)
  156. {
  157. struct saa7191 *decoder = i2c_get_clientdata(client);
  158. u8 stdc = saa7191_read_reg(client, SAA7191_REG_STDC);
  159. u8 ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
  160. u8 chcv = saa7191_read_reg(client, SAA7191_REG_CHCV);
  161. int err;
  162. switch(norm) {
  163. case SAA7191_NORM_PAL:
  164. stdc &= ~SAA7191_STDC_SECS;
  165. ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL);
  166. chcv = SAA7191_CHCV_PAL;
  167. break;
  168. case SAA7191_NORM_NTSC:
  169. stdc &= ~SAA7191_STDC_SECS;
  170. ctl3 &= ~SAA7191_CTL3_AUFD;
  171. ctl3 |= SAA7191_CTL3_FSEL;
  172. chcv = SAA7191_CHCV_NTSC;
  173. break;
  174. case SAA7191_NORM_SECAM:
  175. stdc |= SAA7191_STDC_SECS;
  176. ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL);
  177. chcv = SAA7191_CHCV_PAL;
  178. break;
  179. default:
  180. return -EINVAL;
  181. }
  182. err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
  183. if (err)
  184. return -EIO;
  185. err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc);
  186. if (err)
  187. return -EIO;
  188. err = saa7191_write_reg(client, SAA7191_REG_CHCV, chcv);
  189. if (err)
  190. return -EIO;
  191. decoder->norm = norm;
  192. dprintk("ctl3: %02x stdc: %02x chcv: %02x\n", ctl3,
  193. stdc, chcv);
  194. dprintk("norm: %d\n", norm);
  195. return 0;
  196. }
  197. static int saa7191_wait_for_signal(struct i2c_client *client, u8 *status)
  198. {
  199. int i = 0;
  200. dprintk("Checking for signal...\n");
  201. for (i = 0; i < SAA7191_SYNC_COUNT; i++) {
  202. if (saa7191_read_status(client, status))
  203. return -EIO;
  204. if (((*status) & SAA7191_STATUS_HLCK) == 0) {
  205. dprintk("Signal found\n");
  206. return 0;
  207. }
  208. msleep(SAA7191_SYNC_DELAY);
  209. }
  210. dprintk("No signal\n");
  211. return -EBUSY;
  212. }
  213. static int saa7191_autodetect_norm_extended(struct i2c_client *client)
  214. {
  215. u8 stdc = saa7191_read_reg(client, SAA7191_REG_STDC);
  216. u8 ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
  217. u8 status;
  218. int err = 0;
  219. dprintk("SAA7191 extended signal auto-detection...\n");
  220. stdc &= ~SAA7191_STDC_SECS;
  221. ctl3 &= ~(SAA7191_CTL3_FSEL);
  222. err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc);
  223. if (err) {
  224. err = -EIO;
  225. goto out;
  226. }
  227. err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
  228. if (err) {
  229. err = -EIO;
  230. goto out;
  231. }
  232. ctl3 |= SAA7191_CTL3_AUFD;
  233. err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
  234. if (err) {
  235. err = -EIO;
  236. goto out;
  237. }
  238. msleep(SAA7191_SYNC_DELAY);
  239. err = saa7191_wait_for_signal(client, &status);
  240. if (err)
  241. goto out;
  242. if (status & SAA7191_STATUS_FIDT) {
  243. /* 60Hz signal -> NTSC */
  244. dprintk("60Hz signal: NTSC\n");
  245. return saa7191_set_norm(client, SAA7191_NORM_NTSC);
  246. }
  247. /* 50Hz signal */
  248. dprintk("50Hz signal: Trying PAL...\n");
  249. /* try PAL first */
  250. err = saa7191_set_norm(client, SAA7191_NORM_PAL);
  251. if (err)
  252. goto out;
  253. msleep(SAA7191_SYNC_DELAY);
  254. err = saa7191_wait_for_signal(client, &status);
  255. if (err)
  256. goto out;
  257. /* not 50Hz ? */
  258. if (status & SAA7191_STATUS_FIDT) {
  259. dprintk("No 50Hz signal\n");
  260. err = -EAGAIN;
  261. goto out;
  262. }
  263. if (status & SAA7191_STATUS_CODE) {
  264. dprintk("PAL\n");
  265. return 0;
  266. }
  267. dprintk("No color detected with PAL - Trying SECAM...\n");
  268. /* no color detected ? -> try SECAM */
  269. err = saa7191_set_norm(client,
  270. SAA7191_NORM_SECAM);
  271. if (err)
  272. goto out;
  273. msleep(SAA7191_SYNC_DELAY);
  274. err = saa7191_wait_for_signal(client, &status);
  275. if (err)
  276. goto out;
  277. /* not 50Hz ? */
  278. if (status & SAA7191_STATUS_FIDT) {
  279. dprintk("No 50Hz signal\n");
  280. err = -EAGAIN;
  281. goto out;
  282. }
  283. if (status & SAA7191_STATUS_CODE) {
  284. /* Color detected -> SECAM */
  285. dprintk("SECAM\n");
  286. return 0;
  287. }
  288. dprintk("No color detected with SECAM - Going back to PAL.\n");
  289. /* still no color detected ?
  290. * -> set norm back to PAL */
  291. err = saa7191_set_norm(client,
  292. SAA7191_NORM_PAL);
  293. if (err)
  294. goto out;
  295. out:
  296. ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
  297. if (ctl3 & SAA7191_CTL3_AUFD) {
  298. ctl3 &= ~(SAA7191_CTL3_AUFD);
  299. err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
  300. if (err) {
  301. err = -EIO;
  302. }
  303. }
  304. return err;
  305. }
  306. static int saa7191_autodetect_norm(struct i2c_client *client)
  307. {
  308. u8 status;
  309. dprintk("SAA7191 signal auto-detection...\n");
  310. dprintk("Reading status...\n");
  311. if (saa7191_read_status(client, &status))
  312. return -EIO;
  313. dprintk("Checking for signal...\n");
  314. /* no signal ? */
  315. if (status & SAA7191_STATUS_HLCK) {
  316. dprintk("No signal\n");
  317. return -EBUSY;
  318. }
  319. dprintk("Signal found\n");
  320. if (status & SAA7191_STATUS_FIDT) {
  321. /* 60hz signal -> NTSC */
  322. dprintk("NTSC\n");
  323. return saa7191_set_norm(client, SAA7191_NORM_NTSC);
  324. } else {
  325. /* 50hz signal -> PAL */
  326. dprintk("PAL\n");
  327. return saa7191_set_norm(client, SAA7191_NORM_PAL);
  328. }
  329. }
  330. static int saa7191_get_control(struct i2c_client *client,
  331. struct saa7191_control *ctrl)
  332. {
  333. u8 reg;
  334. int ret = 0;
  335. switch (ctrl->type) {
  336. case SAA7191_CONTROL_BANDPASS:
  337. case SAA7191_CONTROL_BANDPASS_WEIGHT:
  338. case SAA7191_CONTROL_CORING:
  339. reg = saa7191_read_reg(client, SAA7191_REG_LUMA);
  340. switch (ctrl->type) {
  341. case SAA7191_CONTROL_BANDPASS:
  342. ctrl->value = ((s32)reg & SAA7191_LUMA_BPSS_MASK)
  343. >> SAA7191_LUMA_BPSS_SHIFT;
  344. break;
  345. case SAA7191_CONTROL_BANDPASS_WEIGHT:
  346. ctrl->value = ((s32)reg & SAA7191_LUMA_APER_MASK)
  347. >> SAA7191_LUMA_APER_SHIFT;
  348. break;
  349. case SAA7191_CONTROL_CORING:
  350. ctrl->value = ((s32)reg & SAA7191_LUMA_CORI_MASK)
  351. >> SAA7191_LUMA_CORI_SHIFT;
  352. break;
  353. }
  354. break;
  355. case SAA7191_CONTROL_FORCE_COLOUR:
  356. case SAA7191_CONTROL_CHROMA_GAIN:
  357. reg = saa7191_read_reg(client, SAA7191_REG_GAIN);
  358. if (ctrl->type == SAA7191_CONTROL_FORCE_COLOUR)
  359. ctrl->value = ((s32)reg & SAA7191_GAIN_COLO) ? 1 : 0;
  360. else
  361. ctrl->value = ((s32)reg & SAA7191_GAIN_LFIS_MASK)
  362. >> SAA7191_GAIN_LFIS_SHIFT;
  363. break;
  364. case SAA7191_CONTROL_HUE:
  365. reg = saa7191_read_reg(client, SAA7191_REG_HUEC);
  366. if (reg < 0x80)
  367. reg += 0x80;
  368. else
  369. reg -= 0x80;
  370. ctrl->value = (s32)reg;
  371. break;
  372. case SAA7191_CONTROL_VTRC:
  373. reg = saa7191_read_reg(client, SAA7191_REG_STDC);
  374. ctrl->value = ((s32)reg & SAA7191_STDC_VTRC) ? 1 : 0;
  375. break;
  376. case SAA7191_CONTROL_LUMA_DELAY:
  377. reg = saa7191_read_reg(client, SAA7191_REG_CTL3);
  378. ctrl->value = ((s32)reg & SAA7191_CTL3_YDEL_MASK)
  379. >> SAA7191_CTL3_YDEL_SHIFT;
  380. if (ctrl->value >= 4)
  381. ctrl->value -= 8;
  382. break;
  383. case SAA7191_CONTROL_VNR:
  384. reg = saa7191_read_reg(client, SAA7191_REG_CTL4);
  385. ctrl->value = ((s32)reg & SAA7191_CTL4_VNOI_MASK)
  386. >> SAA7191_CTL4_VNOI_SHIFT;
  387. break;
  388. default:
  389. ret = -EINVAL;
  390. }
  391. return ret;
  392. }
  393. static int saa7191_set_control(struct i2c_client *client,
  394. struct saa7191_control *ctrl)
  395. {
  396. u8 reg;
  397. int ret = 0;
  398. switch (ctrl->type) {
  399. case SAA7191_CONTROL_BANDPASS:
  400. case SAA7191_CONTROL_BANDPASS_WEIGHT:
  401. case SAA7191_CONTROL_CORING:
  402. reg = saa7191_read_reg(client, SAA7191_REG_LUMA);
  403. switch (ctrl->type) {
  404. case SAA7191_CONTROL_BANDPASS:
  405. reg &= ~SAA7191_LUMA_BPSS_MASK;
  406. reg |= (ctrl->value << SAA7191_LUMA_BPSS_SHIFT)
  407. & SAA7191_LUMA_BPSS_MASK;
  408. break;
  409. case SAA7191_CONTROL_BANDPASS_WEIGHT:
  410. reg &= ~SAA7191_LUMA_APER_MASK;
  411. reg |= (ctrl->value << SAA7191_LUMA_APER_SHIFT)
  412. & SAA7191_LUMA_APER_MASK;
  413. break;
  414. case SAA7191_CONTROL_CORING:
  415. reg &= ~SAA7191_LUMA_CORI_MASK;
  416. reg |= (ctrl->value << SAA7191_LUMA_CORI_SHIFT)
  417. & SAA7191_LUMA_CORI_MASK;
  418. break;
  419. }
  420. ret = saa7191_write_reg(client, SAA7191_REG_LUMA, reg);
  421. break;
  422. case SAA7191_CONTROL_FORCE_COLOUR:
  423. case SAA7191_CONTROL_CHROMA_GAIN:
  424. reg = saa7191_read_reg(client, SAA7191_REG_GAIN);
  425. if (ctrl->type == SAA7191_CONTROL_FORCE_COLOUR) {
  426. if (ctrl->value)
  427. reg |= SAA7191_GAIN_COLO;
  428. else
  429. reg &= ~SAA7191_GAIN_COLO;
  430. } else {
  431. reg &= ~SAA7191_GAIN_LFIS_MASK;
  432. reg |= (ctrl->value << SAA7191_GAIN_LFIS_SHIFT)
  433. & SAA7191_GAIN_LFIS_MASK;
  434. }
  435. ret = saa7191_write_reg(client, SAA7191_REG_GAIN, reg);
  436. break;
  437. case SAA7191_CONTROL_HUE:
  438. reg = ctrl->value & 0xff;
  439. if (reg < 0x80)
  440. reg += 0x80;
  441. else
  442. reg -= 0x80;
  443. ret = saa7191_write_reg(client, SAA7191_REG_HUEC, reg);
  444. break;
  445. case SAA7191_CONTROL_VTRC:
  446. reg = saa7191_read_reg(client, SAA7191_REG_STDC);
  447. if (ctrl->value)
  448. reg |= SAA7191_STDC_VTRC;
  449. else
  450. reg &= ~SAA7191_STDC_VTRC;
  451. ret = saa7191_write_reg(client, SAA7191_REG_STDC, reg);
  452. break;
  453. case SAA7191_CONTROL_LUMA_DELAY: {
  454. s32 value = ctrl->value;
  455. if (value < 0)
  456. value += 8;
  457. reg = saa7191_read_reg(client, SAA7191_REG_CTL3);
  458. reg &= ~SAA7191_CTL3_YDEL_MASK;
  459. reg |= (value << SAA7191_CTL3_YDEL_SHIFT)
  460. & SAA7191_CTL3_YDEL_MASK;
  461. ret = saa7191_write_reg(client, SAA7191_REG_CTL3, reg);
  462. break;
  463. }
  464. case SAA7191_CONTROL_VNR:
  465. reg = saa7191_read_reg(client, SAA7191_REG_CTL4);
  466. reg &= ~SAA7191_CTL4_VNOI_MASK;
  467. reg |= (ctrl->value << SAA7191_CTL4_VNOI_SHIFT)
  468. & SAA7191_CTL4_VNOI_MASK;
  469. ret = saa7191_write_reg(client, SAA7191_REG_CTL4, reg);
  470. break;
  471. default:
  472. ret = -EINVAL;
  473. }
  474. return ret;
  475. }
  476. /* I2C-interface */
  477. static int saa7191_attach(struct i2c_adapter *adap, int addr, int kind)
  478. {
  479. int err = 0;
  480. struct saa7191 *decoder;
  481. struct i2c_client *client;
  482. printk(KERN_INFO "Philips SAA7191 driver version %s\n",
  483. SAA7191_MODULE_VERSION);
  484. client = kzalloc(sizeof(*client), GFP_KERNEL);
  485. if (!client)
  486. return -ENOMEM;
  487. decoder = kzalloc(sizeof(*decoder), GFP_KERNEL);
  488. if (!decoder) {
  489. err = -ENOMEM;
  490. goto out_free_client;
  491. }
  492. client->addr = addr;
  493. client->adapter = adap;
  494. client->driver = &i2c_driver_saa7191;
  495. client->flags = 0;
  496. strcpy(client->name, "saa7191 client");
  497. i2c_set_clientdata(client, decoder);
  498. decoder->client = client;
  499. err = i2c_attach_client(client);
  500. if (err)
  501. goto out_free_decoder;
  502. err = saa7191_write_block(client, sizeof(initseq), initseq);
  503. if (err) {
  504. printk(KERN_ERR "SAA7191 initialization failed\n");
  505. goto out_detach_client;
  506. }
  507. printk(KERN_INFO "SAA7191 initialized\n");
  508. decoder->input = SAA7191_INPUT_COMPOSITE;
  509. decoder->norm = SAA7191_NORM_PAL;
  510. err = saa7191_autodetect_norm(client);
  511. if (err && (err != -EBUSY)) {
  512. printk(KERN_ERR "SAA7191: Signal auto-detection failed\n");
  513. }
  514. return 0;
  515. out_detach_client:
  516. i2c_detach_client(client);
  517. out_free_decoder:
  518. kfree(decoder);
  519. out_free_client:
  520. kfree(client);
  521. return err;
  522. }
  523. static int saa7191_probe(struct i2c_adapter *adap)
  524. {
  525. /* Always connected to VINO */
  526. if (adap->id == I2C_HW_SGI_VINO)
  527. return saa7191_attach(adap, SAA7191_ADDR, 0);
  528. /* Feel free to add probe here :-) */
  529. return -ENODEV;
  530. }
  531. static int saa7191_detach(struct i2c_client *client)
  532. {
  533. struct saa7191 *decoder = i2c_get_clientdata(client);
  534. i2c_detach_client(client);
  535. kfree(decoder);
  536. kfree(client);
  537. return 0;
  538. }
  539. static int saa7191_command(struct i2c_client *client, unsigned int cmd,
  540. void *arg)
  541. {
  542. struct saa7191 *decoder = i2c_get_clientdata(client);
  543. switch (cmd) {
  544. case DECODER_GET_CAPABILITIES: {
  545. struct video_decoder_capability *cap = arg;
  546. cap->flags = VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC |
  547. VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO;
  548. cap->inputs = (client->adapter->id == I2C_HW_SGI_VINO) ? 2 : 1;
  549. cap->outputs = 1;
  550. break;
  551. }
  552. case DECODER_GET_STATUS: {
  553. int *iarg = arg;
  554. u8 status;
  555. int res = 0;
  556. if (saa7191_read_status(client, &status)) {
  557. return -EIO;
  558. }
  559. if ((status & SAA7191_STATUS_HLCK) == 0)
  560. res |= DECODER_STATUS_GOOD;
  561. if (status & SAA7191_STATUS_CODE)
  562. res |= DECODER_STATUS_COLOR;
  563. switch (decoder->norm) {
  564. case SAA7191_NORM_NTSC:
  565. res |= DECODER_STATUS_NTSC;
  566. break;
  567. case SAA7191_NORM_PAL:
  568. res |= DECODER_STATUS_PAL;
  569. break;
  570. case SAA7191_NORM_SECAM:
  571. res |= DECODER_STATUS_SECAM;
  572. break;
  573. case SAA7191_NORM_AUTO:
  574. default:
  575. if (status & SAA7191_STATUS_FIDT)
  576. res |= DECODER_STATUS_NTSC;
  577. else
  578. res |= DECODER_STATUS_PAL;
  579. break;
  580. }
  581. *iarg = res;
  582. break;
  583. }
  584. case DECODER_SET_NORM: {
  585. int *iarg = arg;
  586. switch (*iarg) {
  587. case VIDEO_MODE_AUTO:
  588. return saa7191_autodetect_norm(client);
  589. case VIDEO_MODE_PAL:
  590. return saa7191_set_norm(client, SAA7191_NORM_PAL);
  591. case VIDEO_MODE_NTSC:
  592. return saa7191_set_norm(client, SAA7191_NORM_NTSC);
  593. case VIDEO_MODE_SECAM:
  594. return saa7191_set_norm(client, SAA7191_NORM_SECAM);
  595. default:
  596. return -EINVAL;
  597. }
  598. break;
  599. }
  600. case DECODER_SET_INPUT: {
  601. int *iarg = arg;
  602. switch (client->adapter->id) {
  603. case I2C_HW_SGI_VINO:
  604. return saa7191_set_input(client, *iarg);
  605. default:
  606. if (*iarg != 0)
  607. return -EINVAL;
  608. }
  609. break;
  610. }
  611. case DECODER_SET_OUTPUT: {
  612. int *iarg = arg;
  613. /* not much choice of outputs */
  614. if (*iarg != 0)
  615. return -EINVAL;
  616. break;
  617. }
  618. case DECODER_ENABLE_OUTPUT: {
  619. /* Always enabled */
  620. break;
  621. }
  622. case DECODER_SET_PICTURE: {
  623. struct video_picture *pic = arg;
  624. unsigned val;
  625. int err;
  626. val = (pic->hue >> 8) - 0x80;
  627. err = saa7191_write_reg(client, SAA7191_REG_HUEC, val);
  628. if (err)
  629. return -EIO;
  630. break;
  631. }
  632. case DECODER_SAA7191_GET_STATUS: {
  633. struct saa7191_status *status = arg;
  634. u8 status_reg;
  635. if (saa7191_read_status(client, &status_reg))
  636. return -EIO;
  637. status->signal = ((status_reg & SAA7191_STATUS_HLCK) == 0)
  638. ? 1 : 0;
  639. status->signal_60hz = (status_reg & SAA7191_STATUS_FIDT)
  640. ? 1 : 0;
  641. status->color = (status_reg & SAA7191_STATUS_CODE) ? 1 : 0;
  642. status->input = decoder->input;
  643. status->norm = decoder->norm;
  644. break;
  645. }
  646. case DECODER_SAA7191_SET_NORM: {
  647. int *norm = arg;
  648. switch (*norm) {
  649. case SAA7191_NORM_AUTO:
  650. return saa7191_autodetect_norm(client);
  651. case SAA7191_NORM_AUTO_EXT:
  652. return saa7191_autodetect_norm_extended(client);
  653. default:
  654. return saa7191_set_norm(client, *norm);
  655. }
  656. }
  657. case DECODER_SAA7191_GET_CONTROL: {
  658. return saa7191_get_control(client, arg);
  659. }
  660. case DECODER_SAA7191_SET_CONTROL: {
  661. return saa7191_set_control(client, arg);
  662. }
  663. default:
  664. return -EINVAL;
  665. }
  666. return 0;
  667. }
  668. static struct i2c_driver i2c_driver_saa7191 = {
  669. .driver = {
  670. .name = "saa7191",
  671. },
  672. .id = I2C_DRIVERID_SAA7191,
  673. .attach_adapter = saa7191_probe,
  674. .detach_client = saa7191_detach,
  675. .command = saa7191_command
  676. };
  677. static int saa7191_init(void)
  678. {
  679. return i2c_add_driver(&i2c_driver_saa7191);
  680. }
  681. static void saa7191_exit(void)
  682. {
  683. i2c_del_driver(&i2c_driver_saa7191);
  684. }
  685. module_init(saa7191_init);
  686. module_exit(saa7191_exit);