adv748x-afe.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559
  1. /*
  2. * Driver for Analog Devices ADV748X 8 channel analog front end (AFE) receiver
  3. * with standard definition processor (SDP)
  4. *
  5. * Copyright (C) 2017 Renesas Electronics Corp.
  6. *
  7. * This program is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU General Public License as published by the
  9. * Free Software Foundation; either version 2 of the License, or (at your
  10. * option) any later version.
  11. */
  12. #include <linux/delay.h>
  13. #include <linux/module.h>
  14. #include <linux/mutex.h>
  15. #include <linux/v4l2-dv-timings.h>
  16. #include <media/v4l2-ctrls.h>
  17. #include <media/v4l2-device.h>
  18. #include <media/v4l2-dv-timings.h>
  19. #include <media/v4l2-ioctl.h>
  20. #include "adv748x.h"
  21. /* -----------------------------------------------------------------------------
  22. * SDP
  23. */
  24. #define ADV748X_AFE_STD_AD_PAL_BG_NTSC_J_SECAM 0x0
  25. #define ADV748X_AFE_STD_AD_PAL_BG_NTSC_J_SECAM_PED 0x1
  26. #define ADV748X_AFE_STD_AD_PAL_N_NTSC_J_SECAM 0x2
  27. #define ADV748X_AFE_STD_AD_PAL_N_NTSC_M_SECAM 0x3
  28. #define ADV748X_AFE_STD_NTSC_J 0x4
  29. #define ADV748X_AFE_STD_NTSC_M 0x5
  30. #define ADV748X_AFE_STD_PAL60 0x6
  31. #define ADV748X_AFE_STD_NTSC_443 0x7
  32. #define ADV748X_AFE_STD_PAL_BG 0x8
  33. #define ADV748X_AFE_STD_PAL_N 0x9
  34. #define ADV748X_AFE_STD_PAL_M 0xa
  35. #define ADV748X_AFE_STD_PAL_M_PED 0xb
  36. #define ADV748X_AFE_STD_PAL_COMB_N 0xc
  37. #define ADV748X_AFE_STD_PAL_COMB_N_PED 0xd
  38. #define ADV748X_AFE_STD_PAL_SECAM 0xe
  39. #define ADV748X_AFE_STD_PAL_SECAM_PED 0xf
  40. static int adv748x_afe_read_ro_map(struct adv748x_state *state, u8 reg)
  41. {
  42. int ret;
  43. /* Select SDP Read-Only Main Map */
  44. ret = sdp_write(state, ADV748X_SDP_MAP_SEL,
  45. ADV748X_SDP_MAP_SEL_RO_MAIN);
  46. if (ret < 0)
  47. return ret;
  48. return sdp_read(state, reg);
  49. }
  50. static int adv748x_afe_status(struct adv748x_afe *afe, u32 *signal,
  51. v4l2_std_id *std)
  52. {
  53. struct adv748x_state *state = adv748x_afe_to_state(afe);
  54. int info;
  55. /* Read status from reg 0x10 of SDP RO Map */
  56. info = adv748x_afe_read_ro_map(state, ADV748X_SDP_RO_10);
  57. if (info < 0)
  58. return info;
  59. if (signal)
  60. *signal = info & ADV748X_SDP_RO_10_IN_LOCK ?
  61. 0 : V4L2_IN_ST_NO_SIGNAL;
  62. if (!std)
  63. return 0;
  64. /* Standard not valid if there is no signal */
  65. if (!(info & ADV748X_SDP_RO_10_IN_LOCK)) {
  66. *std = V4L2_STD_UNKNOWN;
  67. return 0;
  68. }
  69. switch (info & 0x70) {
  70. case 0x00:
  71. *std = V4L2_STD_NTSC;
  72. break;
  73. case 0x10:
  74. *std = V4L2_STD_NTSC_443;
  75. break;
  76. case 0x20:
  77. *std = V4L2_STD_PAL_M;
  78. break;
  79. case 0x30:
  80. *std = V4L2_STD_PAL_60;
  81. break;
  82. case 0x40:
  83. *std = V4L2_STD_PAL;
  84. break;
  85. case 0x50:
  86. *std = V4L2_STD_SECAM;
  87. break;
  88. case 0x60:
  89. *std = V4L2_STD_PAL_Nc | V4L2_STD_PAL_N;
  90. break;
  91. case 0x70:
  92. *std = V4L2_STD_SECAM;
  93. break;
  94. default:
  95. *std = V4L2_STD_UNKNOWN;
  96. break;
  97. }
  98. return 0;
  99. }
  100. static void adv748x_afe_fill_format(struct adv748x_afe *afe,
  101. struct v4l2_mbus_framefmt *fmt)
  102. {
  103. memset(fmt, 0, sizeof(*fmt));
  104. fmt->code = MEDIA_BUS_FMT_UYVY8_2X8;
  105. fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
  106. fmt->field = V4L2_FIELD_ALTERNATE;
  107. fmt->width = 720;
  108. fmt->height = afe->curr_norm & V4L2_STD_525_60 ? 480 : 576;
  109. /* Field height */
  110. fmt->height /= 2;
  111. }
  112. static int adv748x_afe_std(v4l2_std_id std)
  113. {
  114. if (std == V4L2_STD_PAL_60)
  115. return ADV748X_AFE_STD_PAL60;
  116. if (std == V4L2_STD_NTSC_443)
  117. return ADV748X_AFE_STD_NTSC_443;
  118. if (std == V4L2_STD_PAL_N)
  119. return ADV748X_AFE_STD_PAL_N;
  120. if (std == V4L2_STD_PAL_M)
  121. return ADV748X_AFE_STD_PAL_M;
  122. if (std == V4L2_STD_PAL_Nc)
  123. return ADV748X_AFE_STD_PAL_COMB_N;
  124. if (std & V4L2_STD_NTSC)
  125. return ADV748X_AFE_STD_NTSC_M;
  126. if (std & V4L2_STD_PAL)
  127. return ADV748X_AFE_STD_PAL_BG;
  128. if (std & V4L2_STD_SECAM)
  129. return ADV748X_AFE_STD_PAL_SECAM;
  130. return -EINVAL;
  131. }
  132. static void adv748x_afe_set_video_standard(struct adv748x_state *state,
  133. int sdpstd)
  134. {
  135. sdp_clrset(state, ADV748X_SDP_VID_SEL, ADV748X_SDP_VID_SEL_MASK,
  136. (sdpstd & 0xf) << ADV748X_SDP_VID_SEL_SHIFT);
  137. }
  138. static int adv748x_afe_s_input(struct adv748x_afe *afe, unsigned int input)
  139. {
  140. struct adv748x_state *state = adv748x_afe_to_state(afe);
  141. return sdp_write(state, ADV748X_SDP_INSEL, input);
  142. }
  143. static int adv748x_afe_g_pixelaspect(struct v4l2_subdev *sd,
  144. struct v4l2_fract *aspect)
  145. {
  146. struct adv748x_afe *afe = adv748x_sd_to_afe(sd);
  147. if (afe->curr_norm & V4L2_STD_525_60) {
  148. aspect->numerator = 11;
  149. aspect->denominator = 10;
  150. } else {
  151. aspect->numerator = 54;
  152. aspect->denominator = 59;
  153. }
  154. return 0;
  155. }
  156. /* -----------------------------------------------------------------------------
  157. * v4l2_subdev_video_ops
  158. */
  159. static int adv748x_afe_g_std(struct v4l2_subdev *sd, v4l2_std_id *norm)
  160. {
  161. struct adv748x_afe *afe = adv748x_sd_to_afe(sd);
  162. *norm = afe->curr_norm;
  163. return 0;
  164. }
  165. static int adv748x_afe_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
  166. {
  167. struct adv748x_afe *afe = adv748x_sd_to_afe(sd);
  168. struct adv748x_state *state = adv748x_afe_to_state(afe);
  169. int afe_std = adv748x_afe_std(std);
  170. if (afe_std < 0)
  171. return afe_std;
  172. mutex_lock(&state->mutex);
  173. adv748x_afe_set_video_standard(state, afe_std);
  174. afe->curr_norm = std;
  175. mutex_unlock(&state->mutex);
  176. return 0;
  177. }
  178. static int adv748x_afe_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
  179. {
  180. struct adv748x_afe *afe = adv748x_sd_to_afe(sd);
  181. struct adv748x_state *state = adv748x_afe_to_state(afe);
  182. int afe_std;
  183. int ret;
  184. mutex_lock(&state->mutex);
  185. if (afe->streaming) {
  186. ret = -EBUSY;
  187. goto unlock;
  188. }
  189. /* Set auto detect mode */
  190. adv748x_afe_set_video_standard(state,
  191. ADV748X_AFE_STD_AD_PAL_BG_NTSC_J_SECAM);
  192. msleep(100);
  193. /* Read detected standard */
  194. ret = adv748x_afe_status(afe, NULL, std);
  195. afe_std = adv748x_afe_std(afe->curr_norm);
  196. if (afe_std < 0)
  197. goto unlock;
  198. /* Restore original state */
  199. adv748x_afe_set_video_standard(state, afe_std);
  200. unlock:
  201. mutex_unlock(&state->mutex);
  202. return ret;
  203. }
  204. static int adv748x_afe_g_tvnorms(struct v4l2_subdev *sd, v4l2_std_id *norm)
  205. {
  206. *norm = V4L2_STD_ALL;
  207. return 0;
  208. }
  209. static int adv748x_afe_g_input_status(struct v4l2_subdev *sd, u32 *status)
  210. {
  211. struct adv748x_afe *afe = adv748x_sd_to_afe(sd);
  212. struct adv748x_state *state = adv748x_afe_to_state(afe);
  213. int ret;
  214. mutex_lock(&state->mutex);
  215. ret = adv748x_afe_status(afe, status, NULL);
  216. mutex_unlock(&state->mutex);
  217. return ret;
  218. }
  219. static int adv748x_afe_s_stream(struct v4l2_subdev *sd, int enable)
  220. {
  221. struct adv748x_afe *afe = adv748x_sd_to_afe(sd);
  222. struct adv748x_state *state = adv748x_afe_to_state(afe);
  223. u32 signal = V4L2_IN_ST_NO_SIGNAL;
  224. int ret;
  225. mutex_lock(&state->mutex);
  226. if (enable) {
  227. ret = adv748x_afe_s_input(afe, afe->input);
  228. if (ret)
  229. goto unlock;
  230. }
  231. ret = adv748x_txb_power(state, enable);
  232. if (ret)
  233. goto unlock;
  234. afe->streaming = enable;
  235. adv748x_afe_status(afe, &signal, NULL);
  236. if (signal != V4L2_IN_ST_NO_SIGNAL)
  237. adv_dbg(state, "Detected SDP signal\n");
  238. else
  239. adv_dbg(state, "Couldn't detect SDP video signal\n");
  240. unlock:
  241. mutex_unlock(&state->mutex);
  242. return ret;
  243. }
  244. static const struct v4l2_subdev_video_ops adv748x_afe_video_ops = {
  245. .g_std = adv748x_afe_g_std,
  246. .s_std = adv748x_afe_s_std,
  247. .querystd = adv748x_afe_querystd,
  248. .g_tvnorms = adv748x_afe_g_tvnorms,
  249. .g_input_status = adv748x_afe_g_input_status,
  250. .s_stream = adv748x_afe_s_stream,
  251. .g_pixelaspect = adv748x_afe_g_pixelaspect,
  252. };
  253. /* -----------------------------------------------------------------------------
  254. * v4l2_subdev_pad_ops
  255. */
  256. static int adv748x_afe_propagate_pixelrate(struct adv748x_afe *afe)
  257. {
  258. struct v4l2_subdev *tx;
  259. tx = adv748x_get_remote_sd(&afe->pads[ADV748X_AFE_SOURCE]);
  260. if (!tx)
  261. return -ENOLINK;
  262. /*
  263. * The ADV748x ADC sampling frequency is twice the externally supplied
  264. * clock whose frequency is required to be 28.63636 MHz. It oversamples
  265. * with a factor of 4 resulting in a pixel rate of 14.3180180 MHz.
  266. */
  267. return adv748x_csi2_set_pixelrate(tx, 14318180);
  268. }
  269. static int adv748x_afe_enum_mbus_code(struct v4l2_subdev *sd,
  270. struct v4l2_subdev_pad_config *cfg,
  271. struct v4l2_subdev_mbus_code_enum *code)
  272. {
  273. if (code->index != 0)
  274. return -EINVAL;
  275. code->code = MEDIA_BUS_FMT_UYVY8_2X8;
  276. return 0;
  277. }
  278. static int adv748x_afe_get_format(struct v4l2_subdev *sd,
  279. struct v4l2_subdev_pad_config *cfg,
  280. struct v4l2_subdev_format *sdformat)
  281. {
  282. struct adv748x_afe *afe = adv748x_sd_to_afe(sd);
  283. struct v4l2_mbus_framefmt *mbusformat;
  284. /* It makes no sense to get the format of the analog sink pads */
  285. if (sdformat->pad != ADV748X_AFE_SOURCE)
  286. return -EINVAL;
  287. if (sdformat->which == V4L2_SUBDEV_FORMAT_TRY) {
  288. mbusformat = v4l2_subdev_get_try_format(sd, cfg, sdformat->pad);
  289. sdformat->format = *mbusformat;
  290. } else {
  291. adv748x_afe_fill_format(afe, &sdformat->format);
  292. adv748x_afe_propagate_pixelrate(afe);
  293. }
  294. return 0;
  295. }
  296. static int adv748x_afe_set_format(struct v4l2_subdev *sd,
  297. struct v4l2_subdev_pad_config *cfg,
  298. struct v4l2_subdev_format *sdformat)
  299. {
  300. struct v4l2_mbus_framefmt *mbusformat;
  301. /* It makes no sense to get the format of the analog sink pads */
  302. if (sdformat->pad != ADV748X_AFE_SOURCE)
  303. return -EINVAL;
  304. if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE)
  305. return adv748x_afe_get_format(sd, cfg, sdformat);
  306. mbusformat = v4l2_subdev_get_try_format(sd, cfg, sdformat->pad);
  307. *mbusformat = sdformat->format;
  308. return 0;
  309. }
  310. static const struct v4l2_subdev_pad_ops adv748x_afe_pad_ops = {
  311. .enum_mbus_code = adv748x_afe_enum_mbus_code,
  312. .set_fmt = adv748x_afe_set_format,
  313. .get_fmt = adv748x_afe_get_format,
  314. };
  315. /* -----------------------------------------------------------------------------
  316. * v4l2_subdev_ops
  317. */
  318. static const struct v4l2_subdev_ops adv748x_afe_ops = {
  319. .video = &adv748x_afe_video_ops,
  320. .pad = &adv748x_afe_pad_ops,
  321. };
  322. /* -----------------------------------------------------------------------------
  323. * Controls
  324. */
  325. static const char * const afe_ctrl_frp_menu[] = {
  326. "Disabled",
  327. "Solid Blue",
  328. "Color Bars",
  329. "Grey Ramp",
  330. "Cb Ramp",
  331. "Cr Ramp",
  332. "Boundary"
  333. };
  334. static int adv748x_afe_s_ctrl(struct v4l2_ctrl *ctrl)
  335. {
  336. struct adv748x_afe *afe = adv748x_ctrl_to_afe(ctrl);
  337. struct adv748x_state *state = adv748x_afe_to_state(afe);
  338. bool enable;
  339. int ret;
  340. ret = sdp_write(state, 0x0e, 0x00);
  341. if (ret < 0)
  342. return ret;
  343. switch (ctrl->id) {
  344. case V4L2_CID_BRIGHTNESS:
  345. ret = sdp_write(state, ADV748X_SDP_BRI, ctrl->val);
  346. break;
  347. case V4L2_CID_HUE:
  348. /* Hue is inverted according to HSL chart */
  349. ret = sdp_write(state, ADV748X_SDP_HUE, -ctrl->val);
  350. break;
  351. case V4L2_CID_CONTRAST:
  352. ret = sdp_write(state, ADV748X_SDP_CON, ctrl->val);
  353. break;
  354. case V4L2_CID_SATURATION:
  355. ret = sdp_write(state, ADV748X_SDP_SD_SAT_U, ctrl->val);
  356. if (ret)
  357. break;
  358. ret = sdp_write(state, ADV748X_SDP_SD_SAT_V, ctrl->val);
  359. break;
  360. case V4L2_CID_TEST_PATTERN:
  361. enable = !!ctrl->val;
  362. /* Enable/Disable Color bar test patterns */
  363. ret = sdp_clrset(state, ADV748X_SDP_DEF, ADV748X_SDP_DEF_VAL_EN,
  364. enable);
  365. if (ret)
  366. break;
  367. ret = sdp_clrset(state, ADV748X_SDP_FRP, ADV748X_SDP_FRP_MASK,
  368. enable ? ctrl->val - 1 : 0);
  369. break;
  370. default:
  371. return -EINVAL;
  372. }
  373. return ret;
  374. }
  375. static const struct v4l2_ctrl_ops adv748x_afe_ctrl_ops = {
  376. .s_ctrl = adv748x_afe_s_ctrl,
  377. };
  378. static int adv748x_afe_init_controls(struct adv748x_afe *afe)
  379. {
  380. struct adv748x_state *state = adv748x_afe_to_state(afe);
  381. v4l2_ctrl_handler_init(&afe->ctrl_hdl, 5);
  382. /* Use our mutex for the controls */
  383. afe->ctrl_hdl.lock = &state->mutex;
  384. v4l2_ctrl_new_std(&afe->ctrl_hdl, &adv748x_afe_ctrl_ops,
  385. V4L2_CID_BRIGHTNESS, ADV748X_SDP_BRI_MIN,
  386. ADV748X_SDP_BRI_MAX, 1, ADV748X_SDP_BRI_DEF);
  387. v4l2_ctrl_new_std(&afe->ctrl_hdl, &adv748x_afe_ctrl_ops,
  388. V4L2_CID_CONTRAST, ADV748X_SDP_CON_MIN,
  389. ADV748X_SDP_CON_MAX, 1, ADV748X_SDP_CON_DEF);
  390. v4l2_ctrl_new_std(&afe->ctrl_hdl, &adv748x_afe_ctrl_ops,
  391. V4L2_CID_SATURATION, ADV748X_SDP_SAT_MIN,
  392. ADV748X_SDP_SAT_MAX, 1, ADV748X_SDP_SAT_DEF);
  393. v4l2_ctrl_new_std(&afe->ctrl_hdl, &adv748x_afe_ctrl_ops,
  394. V4L2_CID_HUE, ADV748X_SDP_HUE_MIN,
  395. ADV748X_SDP_HUE_MAX, 1, ADV748X_SDP_HUE_DEF);
  396. v4l2_ctrl_new_std_menu_items(&afe->ctrl_hdl, &adv748x_afe_ctrl_ops,
  397. V4L2_CID_TEST_PATTERN,
  398. ARRAY_SIZE(afe_ctrl_frp_menu) - 1,
  399. 0, 0, afe_ctrl_frp_menu);
  400. afe->sd.ctrl_handler = &afe->ctrl_hdl;
  401. if (afe->ctrl_hdl.error) {
  402. v4l2_ctrl_handler_free(&afe->ctrl_hdl);
  403. return afe->ctrl_hdl.error;
  404. }
  405. return v4l2_ctrl_handler_setup(&afe->ctrl_hdl);
  406. }
  407. int adv748x_afe_init(struct adv748x_afe *afe)
  408. {
  409. struct adv748x_state *state = adv748x_afe_to_state(afe);
  410. int ret;
  411. unsigned int i;
  412. afe->input = 0;
  413. afe->streaming = false;
  414. afe->curr_norm = V4L2_STD_NTSC_M;
  415. adv748x_subdev_init(&afe->sd, state, &adv748x_afe_ops,
  416. MEDIA_ENT_F_ATV_DECODER, "afe");
  417. /* Identify the first connector found as a default input if set */
  418. for (i = ADV748X_PORT_AIN0; i <= ADV748X_PORT_AIN7; i++) {
  419. /* Inputs and ports are 1-indexed to match the data sheet */
  420. if (state->endpoints[i]) {
  421. afe->input = i;
  422. break;
  423. }
  424. }
  425. adv748x_afe_s_input(afe, afe->input);
  426. adv_dbg(state, "AFE Default input set to %d\n", afe->input);
  427. /* Entity pads and sinks are 0-indexed to match the pads */
  428. for (i = ADV748X_AFE_SINK_AIN0; i <= ADV748X_AFE_SINK_AIN7; i++)
  429. afe->pads[i].flags = MEDIA_PAD_FL_SINK;
  430. afe->pads[ADV748X_AFE_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
  431. ret = media_entity_pads_init(&afe->sd.entity, ADV748X_AFE_NR_PADS,
  432. afe->pads);
  433. if (ret)
  434. return ret;
  435. ret = adv748x_afe_init_controls(afe);
  436. if (ret)
  437. goto error;
  438. return 0;
  439. error:
  440. media_entity_cleanup(&afe->sd.entity);
  441. return ret;
  442. }
  443. void adv748x_afe_cleanup(struct adv748x_afe *afe)
  444. {
  445. v4l2_device_unregister_subdev(&afe->sd);
  446. media_entity_cleanup(&afe->sd.entity);
  447. v4l2_ctrl_handler_free(&afe->ctrl_hdl);
  448. }