tw9910.c 24 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042
  1. /*
  2. * tw9910 Video Driver
  3. *
  4. * Copyright (C) 2008 Renesas Solutions Corp.
  5. * Kuninori Morimoto <morimoto.kuninori@renesas.com>
  6. *
  7. * Based on ov772x driver,
  8. *
  9. * Copyright (C) 2008 Kuninori Morimoto <morimoto.kuninori@renesas.com>
  10. * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
  11. * Copyright (C) 2008 Magnus Damm
  12. * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
  13. *
  14. * This program is free software; you can redistribute it and/or modify
  15. * it under the terms of the GNU General Public License version 2 as
  16. * published by the Free Software Foundation.
  17. */
  18. #include <linux/init.h>
  19. #include <linux/module.h>
  20. #include <linux/i2c.h>
  21. #include <linux/slab.h>
  22. #include <linux/kernel.h>
  23. #include <linux/delay.h>
  24. #include <linux/videodev2.h>
  25. #include <media/v4l2-chip-ident.h>
  26. #include <media/v4l2-subdev.h>
  27. #include <media/soc_camera.h>
  28. #include <media/tw9910.h>
  29. #define GET_ID(val) ((val & 0xF8) >> 3)
  30. #define GET_REV(val) (val & 0x07)
  31. /*
  32. * register offset
  33. */
  34. #define ID 0x00 /* Product ID Code Register */
  35. #define STATUS1 0x01 /* Chip Status Register I */
  36. #define INFORM 0x02 /* Input Format */
  37. #define OPFORM 0x03 /* Output Format Control Register */
  38. #define DLYCTR 0x04 /* Hysteresis and HSYNC Delay Control */
  39. #define OUTCTR1 0x05 /* Output Control I */
  40. #define ACNTL1 0x06 /* Analog Control Register 1 */
  41. #define CROP_HI 0x07 /* Cropping Register, High */
  42. #define VDELAY_LO 0x08 /* Vertical Delay Register, Low */
  43. #define VACTIVE_LO 0x09 /* Vertical Active Register, Low */
  44. #define HDELAY_LO 0x0A /* Horizontal Delay Register, Low */
  45. #define HACTIVE_LO 0x0B /* Horizontal Active Register, Low */
  46. #define CNTRL1 0x0C /* Control Register I */
  47. #define VSCALE_LO 0x0D /* Vertical Scaling Register, Low */
  48. #define SCALE_HI 0x0E /* Scaling Register, High */
  49. #define HSCALE_LO 0x0F /* Horizontal Scaling Register, Low */
  50. #define BRIGHT 0x10 /* BRIGHTNESS Control Register */
  51. #define CONTRAST 0x11 /* CONTRAST Control Register */
  52. #define SHARPNESS 0x12 /* SHARPNESS Control Register I */
  53. #define SAT_U 0x13 /* Chroma (U) Gain Register */
  54. #define SAT_V 0x14 /* Chroma (V) Gain Register */
  55. #define HUE 0x15 /* Hue Control Register */
  56. #define CORING1 0x17
  57. #define CORING2 0x18 /* Coring and IF compensation */
  58. #define VBICNTL 0x19 /* VBI Control Register */
  59. #define ACNTL2 0x1A /* Analog Control 2 */
  60. #define OUTCTR2 0x1B /* Output Control 2 */
  61. #define SDT 0x1C /* Standard Selection */
  62. #define SDTR 0x1D /* Standard Recognition */
  63. #define TEST 0x1F /* Test Control Register */
  64. #define CLMPG 0x20 /* Clamping Gain */
  65. #define IAGC 0x21 /* Individual AGC Gain */
  66. #define AGCGAIN 0x22 /* AGC Gain */
  67. #define PEAKWT 0x23 /* White Peak Threshold */
  68. #define CLMPL 0x24 /* Clamp level */
  69. #define SYNCT 0x25 /* Sync Amplitude */
  70. #define MISSCNT 0x26 /* Sync Miss Count Register */
  71. #define PCLAMP 0x27 /* Clamp Position Register */
  72. #define VCNTL1 0x28 /* Vertical Control I */
  73. #define VCNTL2 0x29 /* Vertical Control II */
  74. #define CKILL 0x2A /* Color Killer Level Control */
  75. #define COMB 0x2B /* Comb Filter Control */
  76. #define LDLY 0x2C /* Luma Delay and H Filter Control */
  77. #define MISC1 0x2D /* Miscellaneous Control I */
  78. #define LOOP 0x2E /* LOOP Control Register */
  79. #define MISC2 0x2F /* Miscellaneous Control II */
  80. #define MVSN 0x30 /* Macrovision Detection */
  81. #define STATUS2 0x31 /* Chip STATUS II */
  82. #define HFREF 0x32 /* H monitor */
  83. #define CLMD 0x33 /* CLAMP MODE */
  84. #define IDCNTL 0x34 /* ID Detection Control */
  85. #define CLCNTL1 0x35 /* Clamp Control I */
  86. #define ANAPLLCTL 0x4C
  87. #define VBIMIN 0x4D
  88. #define HSLOWCTL 0x4E
  89. #define WSS3 0x4F
  90. #define FILLDATA 0x50
  91. #define SDID 0x51
  92. #define DID 0x52
  93. #define WSS1 0x53
  94. #define WSS2 0x54
  95. #define VVBI 0x55
  96. #define LCTL6 0x56
  97. #define LCTL7 0x57
  98. #define LCTL8 0x58
  99. #define LCTL9 0x59
  100. #define LCTL10 0x5A
  101. #define LCTL11 0x5B
  102. #define LCTL12 0x5C
  103. #define LCTL13 0x5D
  104. #define LCTL14 0x5E
  105. #define LCTL15 0x5F
  106. #define LCTL16 0x60
  107. #define LCTL17 0x61
  108. #define LCTL18 0x62
  109. #define LCTL19 0x63
  110. #define LCTL20 0x64
  111. #define LCTL21 0x65
  112. #define LCTL22 0x66
  113. #define LCTL23 0x67
  114. #define LCTL24 0x68
  115. #define LCTL25 0x69
  116. #define LCTL26 0x6A
  117. #define HSGEGIN 0x6B
  118. #define HSEND 0x6C
  119. #define OVSDLY 0x6D
  120. #define OVSEND 0x6E
  121. #define VBIDELAY 0x6F
  122. /*
  123. * register detail
  124. */
  125. /* INFORM */
  126. #define FC27_ON 0x40 /* 1 : Input crystal clock frequency is 27MHz */
  127. #define FC27_FF 0x00 /* 0 : Square pixel mode. */
  128. /* Must use 24.54MHz for 60Hz field rate */
  129. /* source or 29.5MHz for 50Hz field rate */
  130. #define IFSEL_S 0x10 /* 01 : S-video decoding */
  131. #define IFSEL_C 0x00 /* 00 : Composite video decoding */
  132. /* Y input video selection */
  133. #define YSEL_M0 0x00 /* 00 : Mux0 selected */
  134. #define YSEL_M1 0x04 /* 01 : Mux1 selected */
  135. #define YSEL_M2 0x08 /* 10 : Mux2 selected */
  136. #define YSEL_M3 0x10 /* 11 : Mux3 selected */
  137. /* OPFORM */
  138. #define MODE 0x80 /* 0 : CCIR601 compatible YCrCb 4:2:2 format */
  139. /* 1 : ITU-R-656 compatible data sequence format */
  140. #define LEN 0x40 /* 0 : 8-bit YCrCb 4:2:2 output format */
  141. /* 1 : 16-bit YCrCb 4:2:2 output format.*/
  142. #define LLCMODE 0x20 /* 1 : LLC output mode. */
  143. /* 0 : free-run output mode */
  144. #define AINC 0x10 /* Serial interface auto-indexing control */
  145. /* 0 : auto-increment */
  146. /* 1 : non-auto */
  147. #define VSCTL 0x08 /* 1 : Vertical out ctrl by DVALID */
  148. /* 0 : Vertical out ctrl by HACTIVE and DVALID */
  149. #define OEN 0x04 /* Output Enable together with TRI_SEL. */
  150. /* OUTCTR1 */
  151. #define VSP_LO 0x00 /* 0 : VS pin output polarity is active low */
  152. #define VSP_HI 0x80 /* 1 : VS pin output polarity is active high. */
  153. /* VS pin output control */
  154. #define VSSL_VSYNC 0x00 /* 0 : VSYNC */
  155. #define VSSL_VACT 0x10 /* 1 : VACT */
  156. #define VSSL_FIELD 0x20 /* 2 : FIELD */
  157. #define VSSL_VVALID 0x30 /* 3 : VVALID */
  158. #define VSSL_ZERO 0x70 /* 7 : 0 */
  159. #define HSP_LOW 0x00 /* 0 : HS pin output polarity is active low */
  160. #define HSP_HI 0x08 /* 1 : HS pin output polarity is active high.*/
  161. /* HS pin output control */
  162. #define HSSL_HACT 0x00 /* 0 : HACT */
  163. #define HSSL_HSYNC 0x01 /* 1 : HSYNC */
  164. #define HSSL_DVALID 0x02 /* 2 : DVALID */
  165. #define HSSL_HLOCK 0x03 /* 3 : HLOCK */
  166. #define HSSL_ASYNCW 0x04 /* 4 : ASYNCW */
  167. #define HSSL_ZERO 0x07 /* 7 : 0 */
  168. /* ACNTL1 */
  169. #define SRESET 0x80 /* resets the device to its default state
  170. * but all register content remain unchanged.
  171. * This bit is self-resetting.
  172. */
  173. /* VBICNTL */
  174. /* RTSEL : control the real time signal output from the MPOUT pin */
  175. #define RTSEL_MASK 0x07
  176. #define RTSEL_VLOSS 0x00 /* 0000 = Video loss */
  177. #define RTSEL_HLOCK 0x01 /* 0001 = H-lock */
  178. #define RTSEL_SLOCK 0x02 /* 0010 = S-lock */
  179. #define RTSEL_VLOCK 0x03 /* 0011 = V-lock */
  180. #define RTSEL_MONO 0x04 /* 0100 = MONO */
  181. #define RTSEL_DET50 0x05 /* 0101 = DET50 */
  182. #define RTSEL_FIELD 0x06 /* 0110 = FIELD */
  183. #define RTSEL_RTCO 0x07 /* 0111 = RTCO ( Real Time Control ) */
  184. /*
  185. * structure
  186. */
  187. struct regval_list {
  188. unsigned char reg_num;
  189. unsigned char value;
  190. };
  191. struct tw9910_scale_ctrl {
  192. char *name;
  193. unsigned short width;
  194. unsigned short height;
  195. u16 hscale;
  196. u16 vscale;
  197. };
  198. struct tw9910_cropping_ctrl {
  199. u16 vdelay;
  200. u16 vactive;
  201. u16 hdelay;
  202. u16 hactive;
  203. };
  204. struct tw9910_hsync_ctrl {
  205. u16 start;
  206. u16 end;
  207. };
  208. struct tw9910_priv {
  209. struct v4l2_subdev subdev;
  210. struct tw9910_video_info *info;
  211. const struct tw9910_scale_ctrl *scale;
  212. u32 revision;
  213. };
  214. /*
  215. * register settings
  216. */
  217. #define ENDMARKER { 0xff, 0xff }
  218. static const struct regval_list tw9910_default_regs[] =
  219. {
  220. { OPFORM, 0x00 },
  221. { OUTCTR1, VSP_LO | VSSL_VVALID | HSP_HI | HSSL_HSYNC },
  222. ENDMARKER,
  223. };
  224. static const struct soc_camera_data_format tw9910_color_fmt[] = {
  225. {
  226. .name = "VYUY",
  227. .fourcc = V4L2_PIX_FMT_VYUY,
  228. .depth = 16,
  229. .colorspace = V4L2_COLORSPACE_SMPTE170M,
  230. }
  231. };
  232. static const struct tw9910_scale_ctrl tw9910_ntsc_scales[] = {
  233. {
  234. .name = "NTSC SQ",
  235. .width = 640,
  236. .height = 480,
  237. .hscale = 0x0100,
  238. .vscale = 0x0100,
  239. },
  240. {
  241. .name = "NTSC CCIR601",
  242. .width = 720,
  243. .height = 480,
  244. .hscale = 0x0100,
  245. .vscale = 0x0100,
  246. },
  247. {
  248. .name = "NTSC SQ (CIF)",
  249. .width = 320,
  250. .height = 240,
  251. .hscale = 0x0200,
  252. .vscale = 0x0200,
  253. },
  254. {
  255. .name = "NTSC CCIR601 (CIF)",
  256. .width = 360,
  257. .height = 240,
  258. .hscale = 0x0200,
  259. .vscale = 0x0200,
  260. },
  261. {
  262. .name = "NTSC SQ (QCIF)",
  263. .width = 160,
  264. .height = 120,
  265. .hscale = 0x0400,
  266. .vscale = 0x0400,
  267. },
  268. {
  269. .name = "NTSC CCIR601 (QCIF)",
  270. .width = 180,
  271. .height = 120,
  272. .hscale = 0x0400,
  273. .vscale = 0x0400,
  274. },
  275. };
  276. static const struct tw9910_scale_ctrl tw9910_pal_scales[] = {
  277. {
  278. .name = "PAL SQ",
  279. .width = 768,
  280. .height = 576,
  281. .hscale = 0x0100,
  282. .vscale = 0x0100,
  283. },
  284. {
  285. .name = "PAL CCIR601",
  286. .width = 720,
  287. .height = 576,
  288. .hscale = 0x0100,
  289. .vscale = 0x0100,
  290. },
  291. {
  292. .name = "PAL SQ (CIF)",
  293. .width = 384,
  294. .height = 288,
  295. .hscale = 0x0200,
  296. .vscale = 0x0200,
  297. },
  298. {
  299. .name = "PAL CCIR601 (CIF)",
  300. .width = 360,
  301. .height = 288,
  302. .hscale = 0x0200,
  303. .vscale = 0x0200,
  304. },
  305. {
  306. .name = "PAL SQ (QCIF)",
  307. .width = 192,
  308. .height = 144,
  309. .hscale = 0x0400,
  310. .vscale = 0x0400,
  311. },
  312. {
  313. .name = "PAL CCIR601 (QCIF)",
  314. .width = 180,
  315. .height = 144,
  316. .hscale = 0x0400,
  317. .vscale = 0x0400,
  318. },
  319. };
  320. static const struct tw9910_cropping_ctrl tw9910_cropping_ctrl = {
  321. .vdelay = 0x0012,
  322. .vactive = 0x00F0,
  323. .hdelay = 0x0010,
  324. .hactive = 0x02D0,
  325. };
  326. static const struct tw9910_hsync_ctrl tw9910_hsync_ctrl = {
  327. .start = 0x0260,
  328. .end = 0x0300,
  329. };
  330. /*
  331. * general function
  332. */
  333. static struct tw9910_priv *to_tw9910(const struct i2c_client *client)
  334. {
  335. return container_of(i2c_get_clientdata(client), struct tw9910_priv,
  336. subdev);
  337. }
  338. static int tw9910_set_scale(struct i2c_client *client,
  339. const struct tw9910_scale_ctrl *scale)
  340. {
  341. int ret;
  342. ret = i2c_smbus_write_byte_data(client, SCALE_HI,
  343. (scale->vscale & 0x0F00) >> 4 |
  344. (scale->hscale & 0x0F00) >> 8);
  345. if (ret < 0)
  346. return ret;
  347. ret = i2c_smbus_write_byte_data(client, HSCALE_LO,
  348. scale->hscale & 0x00FF);
  349. if (ret < 0)
  350. return ret;
  351. ret = i2c_smbus_write_byte_data(client, VSCALE_LO,
  352. scale->vscale & 0x00FF);
  353. return ret;
  354. }
  355. static int tw9910_set_cropping(struct i2c_client *client,
  356. const struct tw9910_cropping_ctrl *cropping)
  357. {
  358. int ret;
  359. ret = i2c_smbus_write_byte_data(client, CROP_HI,
  360. (cropping->vdelay & 0x0300) >> 2 |
  361. (cropping->vactive & 0x0300) >> 4 |
  362. (cropping->hdelay & 0x0300) >> 6 |
  363. (cropping->hactive & 0x0300) >> 8);
  364. if (ret < 0)
  365. return ret;
  366. ret = i2c_smbus_write_byte_data(client, VDELAY_LO,
  367. cropping->vdelay & 0x00FF);
  368. if (ret < 0)
  369. return ret;
  370. ret = i2c_smbus_write_byte_data(client, VACTIVE_LO,
  371. cropping->vactive & 0x00FF);
  372. if (ret < 0)
  373. return ret;
  374. ret = i2c_smbus_write_byte_data(client, HDELAY_LO,
  375. cropping->hdelay & 0x00FF);
  376. if (ret < 0)
  377. return ret;
  378. ret = i2c_smbus_write_byte_data(client, HACTIVE_LO,
  379. cropping->hactive & 0x00FF);
  380. return ret;
  381. }
  382. static int tw9910_set_hsync(struct i2c_client *client,
  383. const struct tw9910_hsync_ctrl *hsync)
  384. {
  385. int ret;
  386. /* bit 10 - 3 */
  387. ret = i2c_smbus_write_byte_data(client, HSGEGIN,
  388. (hsync->start & 0x07F8) >> 3);
  389. if (ret < 0)
  390. return ret;
  391. /* bit 10 - 3 */
  392. ret = i2c_smbus_write_byte_data(client, HSEND,
  393. (hsync->end & 0x07F8) >> 3);
  394. if (ret < 0)
  395. return ret;
  396. /* bit 2 - 0 */
  397. ret = i2c_smbus_read_byte_data(client, HSLOWCTL);
  398. if (ret < 0)
  399. return ret;
  400. ret = i2c_smbus_write_byte_data(client, HSLOWCTL,
  401. (ret & 0x88) |
  402. (hsync->start & 0x0007) << 4 |
  403. (hsync->end & 0x0007));
  404. return ret;
  405. }
  406. static int tw9910_write_array(struct i2c_client *client,
  407. const struct regval_list *vals)
  408. {
  409. while (vals->reg_num != 0xff) {
  410. int ret = i2c_smbus_write_byte_data(client,
  411. vals->reg_num,
  412. vals->value);
  413. if (ret < 0)
  414. return ret;
  415. vals++;
  416. }
  417. return 0;
  418. }
  419. static int tw9910_mask_set(struct i2c_client *client, u8 command,
  420. u8 mask, u8 set)
  421. {
  422. s32 val = i2c_smbus_read_byte_data(client, command);
  423. if (val < 0)
  424. return val;
  425. val &= ~mask;
  426. val |= set & mask;
  427. return i2c_smbus_write_byte_data(client, command, val);
  428. }
  429. static void tw9910_reset(struct i2c_client *client)
  430. {
  431. i2c_smbus_write_byte_data(client, ACNTL1, SRESET);
  432. msleep(1);
  433. }
  434. static const struct tw9910_scale_ctrl*
  435. tw9910_select_norm(struct soc_camera_device *icd, u32 width, u32 height)
  436. {
  437. const struct tw9910_scale_ctrl *scale;
  438. const struct tw9910_scale_ctrl *ret = NULL;
  439. v4l2_std_id norm = icd->vdev->current_norm;
  440. __u32 diff = 0xffffffff, tmp;
  441. int size, i;
  442. if (norm & V4L2_STD_NTSC) {
  443. scale = tw9910_ntsc_scales;
  444. size = ARRAY_SIZE(tw9910_ntsc_scales);
  445. } else if (norm & V4L2_STD_PAL) {
  446. scale = tw9910_pal_scales;
  447. size = ARRAY_SIZE(tw9910_pal_scales);
  448. } else {
  449. return NULL;
  450. }
  451. for (i = 0; i < size; i++) {
  452. tmp = abs(width - scale[i].width) +
  453. abs(height - scale[i].height);
  454. if (tmp < diff) {
  455. diff = tmp;
  456. ret = scale + i;
  457. }
  458. }
  459. return ret;
  460. }
  461. /*
  462. * soc_camera_ops function
  463. */
  464. static int tw9910_s_stream(struct v4l2_subdev *sd, int enable)
  465. {
  466. struct i2c_client *client = sd->priv;
  467. struct tw9910_priv *priv = to_tw9910(client);
  468. if (!enable)
  469. return 0;
  470. if (!priv->scale) {
  471. dev_err(&client->dev, "norm select error\n");
  472. return -EPERM;
  473. }
  474. dev_dbg(&client->dev, "%s %dx%d\n",
  475. priv->scale->name,
  476. priv->scale->width,
  477. priv->scale->height);
  478. return 0;
  479. }
  480. static int tw9910_set_bus_param(struct soc_camera_device *icd,
  481. unsigned long flags)
  482. {
  483. return 0;
  484. }
  485. static unsigned long tw9910_query_bus_param(struct soc_camera_device *icd)
  486. {
  487. struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
  488. struct tw9910_priv *priv = to_tw9910(client);
  489. struct soc_camera_link *icl = to_soc_camera_link(icd);
  490. unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
  491. SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
  492. SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth;
  493. return soc_camera_apply_sensor_flags(icl, flags);
  494. }
  495. static int tw9910_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
  496. {
  497. int ret = -EINVAL;
  498. if (norm & (V4L2_STD_NTSC | V4L2_STD_PAL))
  499. ret = 0;
  500. return ret;
  501. }
  502. static int tw9910_enum_input(struct soc_camera_device *icd,
  503. struct v4l2_input *inp)
  504. {
  505. inp->type = V4L2_INPUT_TYPE_TUNER;
  506. inp->std = V4L2_STD_UNKNOWN;
  507. strcpy(inp->name, "Video");
  508. return 0;
  509. }
  510. static int tw9910_g_chip_ident(struct v4l2_subdev *sd,
  511. struct v4l2_dbg_chip_ident *id)
  512. {
  513. struct i2c_client *client = sd->priv;
  514. struct tw9910_priv *priv = to_tw9910(client);
  515. id->ident = V4L2_IDENT_TW9910;
  516. id->revision = priv->revision;
  517. return 0;
  518. }
  519. #ifdef CONFIG_VIDEO_ADV_DEBUG
  520. static int tw9910_g_register(struct v4l2_subdev *sd,
  521. struct v4l2_dbg_register *reg)
  522. {
  523. struct i2c_client *client = sd->priv;
  524. int ret;
  525. if (reg->reg > 0xff)
  526. return -EINVAL;
  527. ret = i2c_smbus_read_byte_data(client, reg->reg);
  528. if (ret < 0)
  529. return ret;
  530. /*
  531. * ret = int
  532. * reg->val = __u64
  533. */
  534. reg->val = (__u64)ret;
  535. return 0;
  536. }
  537. static int tw9910_s_register(struct v4l2_subdev *sd,
  538. struct v4l2_dbg_register *reg)
  539. {
  540. struct i2c_client *client = sd->priv;
  541. if (reg->reg > 0xff ||
  542. reg->val > 0xff)
  543. return -EINVAL;
  544. return i2c_smbus_write_byte_data(client, reg->reg, reg->val);
  545. }
  546. #endif
  547. static int tw9910_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
  548. {
  549. struct v4l2_rect *rect = &a->c;
  550. struct i2c_client *client = sd->priv;
  551. struct tw9910_priv *priv = to_tw9910(client);
  552. struct soc_camera_device *icd = client->dev.platform_data;
  553. int ret = -EINVAL;
  554. u8 val;
  555. /*
  556. * select suitable norm
  557. */
  558. priv->scale = tw9910_select_norm(icd, rect->width, rect->height);
  559. if (!priv->scale)
  560. goto tw9910_set_fmt_error;
  561. /*
  562. * reset hardware
  563. */
  564. tw9910_reset(client);
  565. ret = tw9910_write_array(client, tw9910_default_regs);
  566. if (ret < 0)
  567. goto tw9910_set_fmt_error;
  568. /*
  569. * set bus width
  570. */
  571. val = 0x00;
  572. if (SOCAM_DATAWIDTH_16 == priv->info->buswidth)
  573. val = LEN;
  574. ret = tw9910_mask_set(client, OPFORM, LEN, val);
  575. if (ret < 0)
  576. goto tw9910_set_fmt_error;
  577. /*
  578. * select MPOUT behavior
  579. */
  580. switch (priv->info->mpout) {
  581. case TW9910_MPO_VLOSS:
  582. val = RTSEL_VLOSS; break;
  583. case TW9910_MPO_HLOCK:
  584. val = RTSEL_HLOCK; break;
  585. case TW9910_MPO_SLOCK:
  586. val = RTSEL_SLOCK; break;
  587. case TW9910_MPO_VLOCK:
  588. val = RTSEL_VLOCK; break;
  589. case TW9910_MPO_MONO:
  590. val = RTSEL_MONO; break;
  591. case TW9910_MPO_DET50:
  592. val = RTSEL_DET50; break;
  593. case TW9910_MPO_FIELD:
  594. val = RTSEL_FIELD; break;
  595. case TW9910_MPO_RTCO:
  596. val = RTSEL_RTCO; break;
  597. default:
  598. val = 0;
  599. }
  600. ret = tw9910_mask_set(client, VBICNTL, RTSEL_MASK, val);
  601. if (ret < 0)
  602. goto tw9910_set_fmt_error;
  603. /*
  604. * set scale
  605. */
  606. ret = tw9910_set_scale(client, priv->scale);
  607. if (ret < 0)
  608. goto tw9910_set_fmt_error;
  609. /*
  610. * set cropping
  611. */
  612. ret = tw9910_set_cropping(client, &tw9910_cropping_ctrl);
  613. if (ret < 0)
  614. goto tw9910_set_fmt_error;
  615. /*
  616. * set hsync
  617. */
  618. ret = tw9910_set_hsync(client, &tw9910_hsync_ctrl);
  619. if (ret < 0)
  620. goto tw9910_set_fmt_error;
  621. rect->width = priv->scale->width;
  622. rect->height = priv->scale->height;
  623. rect->left = 0;
  624. rect->top = 0;
  625. return ret;
  626. tw9910_set_fmt_error:
  627. tw9910_reset(client);
  628. priv->scale = NULL;
  629. return ret;
  630. }
  631. static int tw9910_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
  632. {
  633. struct i2c_client *client = sd->priv;
  634. struct tw9910_priv *priv = to_tw9910(client);
  635. if (!priv->scale) {
  636. int ret;
  637. struct v4l2_crop crop = {
  638. .c = {
  639. .left = 0,
  640. .top = 0,
  641. .width = 640,
  642. .height = 480,
  643. },
  644. };
  645. ret = tw9910_s_crop(sd, &crop);
  646. if (ret < 0)
  647. return ret;
  648. }
  649. a->c.left = 0;
  650. a->c.top = 0;
  651. a->c.width = priv->scale->width;
  652. a->c.height = priv->scale->height;
  653. a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  654. return 0;
  655. }
  656. static int tw9910_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
  657. {
  658. a->bounds.left = 0;
  659. a->bounds.top = 0;
  660. a->bounds.width = 768;
  661. a->bounds.height = 576;
  662. a->defrect.left = 0;
  663. a->defrect.top = 0;
  664. a->defrect.width = 640;
  665. a->defrect.height = 480;
  666. a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  667. a->pixelaspect.numerator = 1;
  668. a->pixelaspect.denominator = 1;
  669. return 0;
  670. }
  671. static int tw9910_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
  672. {
  673. struct i2c_client *client = sd->priv;
  674. struct tw9910_priv *priv = to_tw9910(client);
  675. struct v4l2_pix_format *pix = &f->fmt.pix;
  676. if (!priv->scale) {
  677. int ret;
  678. struct v4l2_crop crop = {
  679. .c = {
  680. .left = 0,
  681. .top = 0,
  682. .width = 640,
  683. .height = 480,
  684. },
  685. };
  686. ret = tw9910_s_crop(sd, &crop);
  687. if (ret < 0)
  688. return ret;
  689. }
  690. f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  691. pix->width = priv->scale->width;
  692. pix->height = priv->scale->height;
  693. pix->pixelformat = V4L2_PIX_FMT_VYUY;
  694. pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
  695. pix->field = V4L2_FIELD_INTERLACED;
  696. return 0;
  697. }
  698. static int tw9910_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
  699. {
  700. struct i2c_client *client = sd->priv;
  701. struct tw9910_priv *priv = to_tw9910(client);
  702. struct v4l2_pix_format *pix = &f->fmt.pix;
  703. /* See tw9910_s_crop() - no proper cropping support */
  704. struct v4l2_crop a = {
  705. .c = {
  706. .left = 0,
  707. .top = 0,
  708. .width = pix->width,
  709. .height = pix->height,
  710. },
  711. };
  712. int i, ret;
  713. /*
  714. * check color format
  715. */
  716. for (i = 0; i < ARRAY_SIZE(tw9910_color_fmt); i++)
  717. if (pix->pixelformat == tw9910_color_fmt[i].fourcc)
  718. break;
  719. if (i == ARRAY_SIZE(tw9910_color_fmt))
  720. return -EINVAL;
  721. ret = tw9910_s_crop(sd, &a);
  722. if (!ret) {
  723. pix->width = priv->scale->width;
  724. pix->height = priv->scale->height;
  725. }
  726. return ret;
  727. }
  728. static int tw9910_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
  729. {
  730. struct i2c_client *client = sd->priv;
  731. struct soc_camera_device *icd = client->dev.platform_data;
  732. struct v4l2_pix_format *pix = &f->fmt.pix;
  733. const struct tw9910_scale_ctrl *scale;
  734. if (V4L2_FIELD_ANY == pix->field) {
  735. pix->field = V4L2_FIELD_INTERLACED;
  736. } else if (V4L2_FIELD_INTERLACED != pix->field) {
  737. dev_err(&client->dev, "Field type invalid.\n");
  738. return -EINVAL;
  739. }
  740. /*
  741. * select suitable norm
  742. */
  743. scale = tw9910_select_norm(icd, pix->width, pix->height);
  744. if (!scale)
  745. return -EINVAL;
  746. pix->width = scale->width;
  747. pix->height = scale->height;
  748. return 0;
  749. }
  750. static int tw9910_video_probe(struct soc_camera_device *icd,
  751. struct i2c_client *client)
  752. {
  753. struct tw9910_priv *priv = to_tw9910(client);
  754. s32 id;
  755. /*
  756. * We must have a parent by now. And it cannot be a wrong one.
  757. * So this entire test is completely redundant.
  758. */
  759. if (!icd->dev.parent ||
  760. to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
  761. return -ENODEV;
  762. /*
  763. * tw9910 only use 8 or 16 bit bus width
  764. */
  765. if (SOCAM_DATAWIDTH_16 != priv->info->buswidth &&
  766. SOCAM_DATAWIDTH_8 != priv->info->buswidth) {
  767. dev_err(&client->dev, "bus width error\n");
  768. return -ENODEV;
  769. }
  770. icd->formats = tw9910_color_fmt;
  771. icd->num_formats = ARRAY_SIZE(tw9910_color_fmt);
  772. /*
  773. * check and show Product ID
  774. * So far only revisions 0 and 1 have been seen
  775. */
  776. id = i2c_smbus_read_byte_data(client, ID);
  777. priv->revision = GET_REV(id);
  778. id = GET_ID(id);
  779. if (0x0B != id ||
  780. 0x01 < priv->revision) {
  781. dev_err(&client->dev,
  782. "Product ID error %x:%x\n",
  783. id, priv->revision);
  784. return -ENODEV;
  785. }
  786. dev_info(&client->dev,
  787. "tw9910 Product ID %0x:%0x\n", id, priv->revision);
  788. icd->vdev->tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL;
  789. icd->vdev->current_norm = V4L2_STD_NTSC;
  790. return 0;
  791. }
  792. static struct soc_camera_ops tw9910_ops = {
  793. .set_bus_param = tw9910_set_bus_param,
  794. .query_bus_param = tw9910_query_bus_param,
  795. .enum_input = tw9910_enum_input,
  796. };
  797. static struct v4l2_subdev_core_ops tw9910_subdev_core_ops = {
  798. .g_chip_ident = tw9910_g_chip_ident,
  799. .s_std = tw9910_s_std,
  800. #ifdef CONFIG_VIDEO_ADV_DEBUG
  801. .g_register = tw9910_g_register,
  802. .s_register = tw9910_s_register,
  803. #endif
  804. };
  805. static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = {
  806. .s_stream = tw9910_s_stream,
  807. .g_fmt = tw9910_g_fmt,
  808. .s_fmt = tw9910_s_fmt,
  809. .try_fmt = tw9910_try_fmt,
  810. .cropcap = tw9910_cropcap,
  811. .g_crop = tw9910_g_crop,
  812. .s_crop = tw9910_s_crop,
  813. };
  814. static struct v4l2_subdev_ops tw9910_subdev_ops = {
  815. .core = &tw9910_subdev_core_ops,
  816. .video = &tw9910_subdev_video_ops,
  817. };
  818. /*
  819. * i2c_driver function
  820. */
  821. static int tw9910_probe(struct i2c_client *client,
  822. const struct i2c_device_id *did)
  823. {
  824. struct tw9910_priv *priv;
  825. struct tw9910_video_info *info;
  826. struct soc_camera_device *icd = client->dev.platform_data;
  827. struct i2c_adapter *adapter =
  828. to_i2c_adapter(client->dev.parent);
  829. struct soc_camera_link *icl;
  830. int ret;
  831. if (!icd) {
  832. dev_err(&client->dev, "TW9910: missing soc-camera data!\n");
  833. return -EINVAL;
  834. }
  835. icl = to_soc_camera_link(icd);
  836. if (!icl || !icl->priv)
  837. return -EINVAL;
  838. info = icl->priv;
  839. if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
  840. dev_err(&client->dev,
  841. "I2C-Adapter doesn't support "
  842. "I2C_FUNC_SMBUS_BYTE_DATA\n");
  843. return -EIO;
  844. }
  845. priv = kzalloc(sizeof(*priv), GFP_KERNEL);
  846. if (!priv)
  847. return -ENOMEM;
  848. priv->info = info;
  849. v4l2_i2c_subdev_init(&priv->subdev, client, &tw9910_subdev_ops);
  850. icd->ops = &tw9910_ops;
  851. icd->iface = icl->bus_id;
  852. ret = tw9910_video_probe(icd, client);
  853. if (ret) {
  854. icd->ops = NULL;
  855. i2c_set_clientdata(client, NULL);
  856. kfree(priv);
  857. }
  858. return ret;
  859. }
  860. static int tw9910_remove(struct i2c_client *client)
  861. {
  862. struct tw9910_priv *priv = to_tw9910(client);
  863. struct soc_camera_device *icd = client->dev.platform_data;
  864. icd->ops = NULL;
  865. i2c_set_clientdata(client, NULL);
  866. kfree(priv);
  867. return 0;
  868. }
  869. static const struct i2c_device_id tw9910_id[] = {
  870. { "tw9910", 0 },
  871. { }
  872. };
  873. MODULE_DEVICE_TABLE(i2c, tw9910_id);
  874. static struct i2c_driver tw9910_i2c_driver = {
  875. .driver = {
  876. .name = "tw9910",
  877. },
  878. .probe = tw9910_probe,
  879. .remove = tw9910_remove,
  880. .id_table = tw9910_id,
  881. };
  882. /*
  883. * module function
  884. */
  885. static int __init tw9910_module_init(void)
  886. {
  887. return i2c_add_driver(&tw9910_i2c_driver);
  888. }
  889. static void __exit tw9910_module_exit(void)
  890. {
  891. i2c_del_driver(&tw9910_i2c_driver);
  892. }
  893. module_init(tw9910_module_init);
  894. module_exit(tw9910_module_exit);
  895. MODULE_DESCRIPTION("SoC Camera driver for tw9910");
  896. MODULE_AUTHOR("Kuninori Morimoto");
  897. MODULE_LICENSE("GPL v2");