aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/i2c/adv7511.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/i2c/adv7511.c')
-rw-r--r--drivers/media/i2c/adv7511.c229
1 files changed, 222 insertions, 7 deletions
diff --git a/drivers/media/i2c/adv7511.c b/drivers/media/i2c/adv7511.c
index f98acf4aafd4..81736aaf0f31 100644
--- a/drivers/media/i2c/adv7511.c
+++ b/drivers/media/i2c/adv7511.c
@@ -26,6 +26,7 @@
26#include <linux/videodev2.h> 26#include <linux/videodev2.h>
27#include <linux/gpio.h> 27#include <linux/gpio.h>
28#include <linux/workqueue.h> 28#include <linux/workqueue.h>
29#include <linux/hdmi.h>
29#include <linux/v4l2-dv-timings.h> 30#include <linux/v4l2-dv-timings.h>
30#include <media/v4l2-device.h> 31#include <media/v4l2-device.h>
31#include <media/v4l2-common.h> 32#include <media/v4l2-common.h>
@@ -96,6 +97,10 @@ struct adv7511_state {
96 bool have_monitor; 97 bool have_monitor;
97 /* timings from s_dv_timings */ 98 /* timings from s_dv_timings */
98 struct v4l2_dv_timings dv_timings; 99 struct v4l2_dv_timings dv_timings;
100 u32 fmt_code;
101 u32 colorspace;
102 u32 ycbcr_enc;
103 u32 quantization;
99 /* controls */ 104 /* controls */
100 struct v4l2_ctrl *hdmi_mode_ctrl; 105 struct v4l2_ctrl *hdmi_mode_ctrl;
101 struct v4l2_ctrl *hotplug_ctrl; 106 struct v4l2_ctrl *hotplug_ctrl;
@@ -779,26 +784,234 @@ static int adv7511_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
779{ 784{
780 struct adv7511_state *state = get_adv7511_state(sd); 785 struct adv7511_state *state = get_adv7511_state(sd);
781 786
787 memset(edid->reserved, 0, sizeof(edid->reserved));
788
782 if (edid->pad != 0) 789 if (edid->pad != 0)
783 return -EINVAL; 790 return -EINVAL;
784 if ((edid->blocks == 0) || (edid->blocks > 256)) 791
785 return -EINVAL; 792 if (edid->start_block == 0 && edid->blocks == 0) {
786 if (!state->edid.segments) { 793 edid->blocks = state->edid.segments * 2;
787 v4l2_dbg(1, debug, sd, "EDID segment 0 not found\n"); 794 return 0;
788 return -ENODATA;
789 } 795 }
796
797 if (state->edid.segments == 0)
798 return -ENODATA;
799
790 if (edid->start_block >= state->edid.segments * 2) 800 if (edid->start_block >= state->edid.segments * 2)
791 return -E2BIG; 801 return -EINVAL;
792 if ((edid->blocks + edid->start_block) >= state->edid.segments * 2) 802
803 if (edid->start_block + edid->blocks > state->edid.segments * 2)
793 edid->blocks = state->edid.segments * 2 - edid->start_block; 804 edid->blocks = state->edid.segments * 2 - edid->start_block;
794 805
795 memcpy(edid->edid, &state->edid.data[edid->start_block * 128], 806 memcpy(edid->edid, &state->edid.data[edid->start_block * 128],
796 128 * edid->blocks); 807 128 * edid->blocks);
808
809 return 0;
810}
811
812static int adv7511_enum_mbus_code(struct v4l2_subdev *sd,
813 struct v4l2_subdev_fh *fh,
814 struct v4l2_subdev_mbus_code_enum *code)
815{
816 if (code->pad != 0)
817 return -EINVAL;
818
819 switch (code->index) {
820 case 0:
821 code->code = MEDIA_BUS_FMT_RGB888_1X24;
822 break;
823 case 1:
824 code->code = MEDIA_BUS_FMT_YUYV8_1X16;
825 break;
826 case 2:
827 code->code = MEDIA_BUS_FMT_UYVY8_1X16;
828 break;
829 default:
830 return -EINVAL;
831 }
832 return 0;
833}
834
835static void adv7511_fill_format(struct adv7511_state *state,
836 struct v4l2_mbus_framefmt *format)
837{
838 memset(format, 0, sizeof(*format));
839
840 format->width = state->dv_timings.bt.width;
841 format->height = state->dv_timings.bt.height;
842 format->field = V4L2_FIELD_NONE;
843}
844
845static int adv7511_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
846 struct v4l2_subdev_format *format)
847{
848 struct adv7511_state *state = get_adv7511_state(sd);
849
850 if (format->pad != 0)
851 return -EINVAL;
852
853 adv7511_fill_format(state, &format->format);
854
855 if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
856 struct v4l2_mbus_framefmt *fmt;
857
858 fmt = v4l2_subdev_get_try_format(fh, format->pad);
859 format->format.code = fmt->code;
860 format->format.colorspace = fmt->colorspace;
861 format->format.ycbcr_enc = fmt->ycbcr_enc;
862 format->format.quantization = fmt->quantization;
863 } else {
864 format->format.code = state->fmt_code;
865 format->format.colorspace = state->colorspace;
866 format->format.ycbcr_enc = state->ycbcr_enc;
867 format->format.quantization = state->quantization;
868 }
869
870 return 0;
871}
872
873static int adv7511_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
874 struct v4l2_subdev_format *format)
875{
876 struct adv7511_state *state = get_adv7511_state(sd);
877 /*
878 * Bitfield namings come the CEA-861-F standard, table 8 "Auxiliary
879 * Video Information (AVI) InfoFrame Format"
880 *
881 * c = Colorimetry
882 * ec = Extended Colorimetry
883 * y = RGB or YCbCr
884 * q = RGB Quantization Range
885 * yq = YCC Quantization Range
886 */
887 u8 c = HDMI_COLORIMETRY_NONE;
888 u8 ec = HDMI_EXTENDED_COLORIMETRY_XV_YCC_601;
889 u8 y = HDMI_COLORSPACE_RGB;
890 u8 q = HDMI_QUANTIZATION_RANGE_DEFAULT;
891 u8 yq = HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
892
893 if (format->pad != 0)
894 return -EINVAL;
895 switch (format->format.code) {
896 case MEDIA_BUS_FMT_UYVY8_1X16:
897 case MEDIA_BUS_FMT_YUYV8_1X16:
898 case MEDIA_BUS_FMT_RGB888_1X24:
899 break;
900 default:
901 return -EINVAL;
902 }
903
904 adv7511_fill_format(state, &format->format);
905 if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
906 struct v4l2_mbus_framefmt *fmt;
907
908 fmt = v4l2_subdev_get_try_format(fh, format->pad);
909 fmt->code = format->format.code;
910 fmt->colorspace = format->format.colorspace;
911 fmt->ycbcr_enc = format->format.ycbcr_enc;
912 fmt->quantization = format->format.quantization;
913 return 0;
914 }
915
916 switch (format->format.code) {
917 case MEDIA_BUS_FMT_UYVY8_1X16:
918 adv7511_wr_and_or(sd, 0x15, 0xf0, 0x01);
919 adv7511_wr_and_or(sd, 0x16, 0x03, 0xb8);
920 y = HDMI_COLORSPACE_YUV422;
921 break;
922 case MEDIA_BUS_FMT_YUYV8_1X16:
923 adv7511_wr_and_or(sd, 0x15, 0xf0, 0x01);
924 adv7511_wr_and_or(sd, 0x16, 0x03, 0xbc);
925 y = HDMI_COLORSPACE_YUV422;
926 break;
927 case MEDIA_BUS_FMT_RGB888_1X24:
928 default:
929 adv7511_wr_and_or(sd, 0x15, 0xf0, 0x00);
930 adv7511_wr_and_or(sd, 0x16, 0x03, 0x00);
931 break;
932 }
933 state->fmt_code = format->format.code;
934 state->colorspace = format->format.colorspace;
935 state->ycbcr_enc = format->format.ycbcr_enc;
936 state->quantization = format->format.quantization;
937
938 switch (format->format.colorspace) {
939 case V4L2_COLORSPACE_ADOBERGB:
940 c = HDMI_COLORIMETRY_EXTENDED;
941 ec = y ? HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601 :
942 HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB;
943 break;
944 case V4L2_COLORSPACE_SMPTE170M:
945 c = y ? HDMI_COLORIMETRY_ITU_601 : HDMI_COLORIMETRY_NONE;
946 if (y && format->format.ycbcr_enc == V4L2_YCBCR_ENC_XV601) {
947 c = HDMI_COLORIMETRY_EXTENDED;
948 ec = HDMI_EXTENDED_COLORIMETRY_XV_YCC_601;
949 }
950 break;
951 case V4L2_COLORSPACE_REC709:
952 c = y ? HDMI_COLORIMETRY_ITU_709 : HDMI_COLORIMETRY_NONE;
953 if (y && format->format.ycbcr_enc == V4L2_YCBCR_ENC_XV709) {
954 c = HDMI_COLORIMETRY_EXTENDED;
955 ec = HDMI_EXTENDED_COLORIMETRY_XV_YCC_709;
956 }
957 break;
958 case V4L2_COLORSPACE_SRGB:
959 c = y ? HDMI_COLORIMETRY_EXTENDED : HDMI_COLORIMETRY_NONE;
960 ec = y ? HDMI_EXTENDED_COLORIMETRY_S_YCC_601 :
961 HDMI_EXTENDED_COLORIMETRY_XV_YCC_601;
962 break;
963 case V4L2_COLORSPACE_BT2020:
964 c = HDMI_COLORIMETRY_EXTENDED;
965 if (y && format->format.ycbcr_enc == V4L2_YCBCR_ENC_BT2020_CONST_LUM)
966 ec = 5; /* Not yet available in hdmi.h */
967 else
968 ec = 6; /* Not yet available in hdmi.h */
969 break;
970 default:
971 break;
972 }
973
974 /*
975 * CEA-861-F says that for RGB formats the YCC range must match the
976 * RGB range, although sources should ignore the YCC range.
977 *
978 * The RGB quantization range shouldn't be non-zero if the EDID doesn't
979 * have the Q bit set in the Video Capabilities Data Block, however this
980 * isn't checked at the moment. The assumption is that the application
981 * knows the EDID and can detect this.
982 *
983 * The same is true for the YCC quantization range: non-standard YCC
984 * quantization ranges should only be sent if the EDID has the YQ bit
985 * set in the Video Capabilities Data Block.
986 */
987 switch (format->format.quantization) {
988 case V4L2_QUANTIZATION_FULL_RANGE:
989 q = y ? HDMI_QUANTIZATION_RANGE_DEFAULT :
990 HDMI_QUANTIZATION_RANGE_FULL;
991 yq = q ? q - 1 : HDMI_YCC_QUANTIZATION_RANGE_FULL;
992 break;
993 case V4L2_QUANTIZATION_LIM_RANGE:
994 q = y ? HDMI_QUANTIZATION_RANGE_DEFAULT :
995 HDMI_QUANTIZATION_RANGE_LIMITED;
996 yq = q ? q - 1 : HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
997 break;
998 }
999
1000 adv7511_wr_and_or(sd, 0x4a, 0xbf, 0);
1001 adv7511_wr_and_or(sd, 0x55, 0x9f, y << 5);
1002 adv7511_wr_and_or(sd, 0x56, 0x3f, c << 6);
1003 adv7511_wr_and_or(sd, 0x57, 0x83, (ec << 4) | (q << 2));
1004 adv7511_wr_and_or(sd, 0x59, 0x0f, yq << 4);
1005 adv7511_wr_and_or(sd, 0x4a, 0xff, 1);
1006
797 return 0; 1007 return 0;
798} 1008}
799 1009
800static const struct v4l2_subdev_pad_ops adv7511_pad_ops = { 1010static const struct v4l2_subdev_pad_ops adv7511_pad_ops = {
801 .get_edid = adv7511_get_edid, 1011 .get_edid = adv7511_get_edid,
1012 .enum_mbus_code = adv7511_enum_mbus_code,
1013 .get_fmt = adv7511_get_fmt,
1014 .set_fmt = adv7511_set_fmt,
802 .enum_dv_timings = adv7511_enum_dv_timings, 1015 .enum_dv_timings = adv7511_enum_dv_timings,
803 .dv_timings_cap = adv7511_dv_timings_cap, 1016 .dv_timings_cap = adv7511_dv_timings_cap,
804}; 1017};
@@ -1116,6 +1329,8 @@ static int adv7511_probe(struct i2c_client *client, const struct i2c_device_id *
1116 return -ENODEV; 1329 return -ENODEV;
1117 } 1330 }
1118 memcpy(&state->pdata, pdata, sizeof(state->pdata)); 1331 memcpy(&state->pdata, pdata, sizeof(state->pdata));
1332 state->fmt_code = MEDIA_BUS_FMT_RGB888_1X24;
1333 state->colorspace = V4L2_COLORSPACE_SRGB;
1119 1334
1120 sd = &state->sd; 1335 sd = &state->sd;
1121 1336