diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2014-01-26 16:42:37 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-05-25 11:57:26 -0400 |
commit | 539b33b05913f1de34c7e0ef3376347ffd273e8f (patch) | |
tree | a55dae970177bd6ebeb6d456f5ba43b421e916b0 /drivers/media | |
parent | c784b1e2ece8a591263050d1f59607547dfad8f3 (diff) |
[media] adv7604: Make output format configurable through pad format operations
Replace the dummy video format operations by pad format operations that
configure the output format.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Hans Verkuil <hans.verkuil@cisco.com>
Tested-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/i2c/adv7604.c | 280 |
1 files changed, 255 insertions, 25 deletions
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index 79fb34d5ee2d..59f7bf0723fe 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c | |||
@@ -53,6 +53,28 @@ MODULE_LICENSE("GPL"); | |||
53 | /* ADV7604 system clock frequency */ | 53 | /* ADV7604 system clock frequency */ |
54 | #define ADV7604_fsc (28636360) | 54 | #define ADV7604_fsc (28636360) |
55 | 55 | ||
56 | #define ADV7604_RGB_OUT (1 << 1) | ||
57 | |||
58 | #define ADV7604_OP_FORMAT_SEL_8BIT (0 << 0) | ||
59 | #define ADV7604_OP_FORMAT_SEL_10BIT (1 << 0) | ||
60 | #define ADV7604_OP_FORMAT_SEL_12BIT (2 << 0) | ||
61 | |||
62 | #define ADV7604_OP_MODE_SEL_SDR_422 (0 << 5) | ||
63 | #define ADV7604_OP_MODE_SEL_DDR_422 (1 << 5) | ||
64 | #define ADV7604_OP_MODE_SEL_SDR_444 (2 << 5) | ||
65 | #define ADV7604_OP_MODE_SEL_DDR_444 (3 << 5) | ||
66 | #define ADV7604_OP_MODE_SEL_SDR_422_2X (4 << 5) | ||
67 | #define ADV7604_OP_MODE_SEL_ADI_CM (5 << 5) | ||
68 | |||
69 | #define ADV7604_OP_CH_SEL_GBR (0 << 5) | ||
70 | #define ADV7604_OP_CH_SEL_GRB (1 << 5) | ||
71 | #define ADV7604_OP_CH_SEL_BGR (2 << 5) | ||
72 | #define ADV7604_OP_CH_SEL_RGB (3 << 5) | ||
73 | #define ADV7604_OP_CH_SEL_BRG (4 << 5) | ||
74 | #define ADV7604_OP_CH_SEL_RBG (5 << 5) | ||
75 | |||
76 | #define ADV7604_OP_SWAP_CB_CR (1 << 0) | ||
77 | |||
56 | enum adv7604_type { | 78 | enum adv7604_type { |
57 | ADV7604, | 79 | ADV7604, |
58 | ADV7611, | 80 | ADV7611, |
@@ -63,6 +85,14 @@ struct adv7604_reg_seq { | |||
63 | u8 val; | 85 | u8 val; |
64 | }; | 86 | }; |
65 | 87 | ||
88 | struct adv7604_format_info { | ||
89 | enum v4l2_mbus_pixelcode code; | ||
90 | u8 op_ch_sel; | ||
91 | bool rgb_out; | ||
92 | bool swap_cb_cr; | ||
93 | u8 op_format_sel; | ||
94 | }; | ||
95 | |||
66 | struct adv7604_chip_info { | 96 | struct adv7604_chip_info { |
67 | enum adv7604_type type; | 97 | enum adv7604_type type; |
68 | 98 | ||
@@ -78,6 +108,9 @@ struct adv7604_chip_info { | |||
78 | unsigned int tdms_lock_mask; | 108 | unsigned int tdms_lock_mask; |
79 | unsigned int fmt_change_digital_mask; | 109 | unsigned int fmt_change_digital_mask; |
80 | 110 | ||
111 | const struct adv7604_format_info *formats; | ||
112 | unsigned int nformats; | ||
113 | |||
81 | void (*set_termination)(struct v4l2_subdev *sd, bool enable); | 114 | void (*set_termination)(struct v4l2_subdev *sd, bool enable); |
82 | void (*setup_irqs)(struct v4l2_subdev *sd); | 115 | void (*setup_irqs)(struct v4l2_subdev *sd); |
83 | unsigned int (*read_hdmi_pixelclock)(struct v4l2_subdev *sd); | 116 | unsigned int (*read_hdmi_pixelclock)(struct v4l2_subdev *sd); |
@@ -101,12 +134,18 @@ struct adv7604_chip_info { | |||
101 | struct adv7604_state { | 134 | struct adv7604_state { |
102 | const struct adv7604_chip_info *info; | 135 | const struct adv7604_chip_info *info; |
103 | struct adv7604_platform_data pdata; | 136 | struct adv7604_platform_data pdata; |
137 | |||
104 | struct v4l2_subdev sd; | 138 | struct v4l2_subdev sd; |
105 | struct media_pad pads[ADV7604_PAD_MAX]; | 139 | struct media_pad pads[ADV7604_PAD_MAX]; |
106 | unsigned int source_pad; | 140 | unsigned int source_pad; |
141 | |||
107 | struct v4l2_ctrl_handler hdl; | 142 | struct v4l2_ctrl_handler hdl; |
143 | |||
108 | enum adv7604_pad selected_input; | 144 | enum adv7604_pad selected_input; |
145 | |||
109 | struct v4l2_dv_timings timings; | 146 | struct v4l2_dv_timings timings; |
147 | const struct adv7604_format_info *format; | ||
148 | |||
110 | struct { | 149 | struct { |
111 | u8 edid[256]; | 150 | u8 edid[256]; |
112 | u32 present; | 151 | u32 present; |
@@ -771,6 +810,93 @@ static void adv7604_write_reg_seq(struct v4l2_subdev *sd, | |||
771 | adv7604_write_reg(sd, reg_seq[i].reg, reg_seq[i].val); | 810 | adv7604_write_reg(sd, reg_seq[i].reg, reg_seq[i].val); |
772 | } | 811 | } |
773 | 812 | ||
813 | /* ----------------------------------------------------------------------------- | ||
814 | * Format helpers | ||
815 | */ | ||
816 | |||
817 | static const struct adv7604_format_info adv7604_formats[] = { | ||
818 | { V4L2_MBUS_FMT_RGB888_1X24, ADV7604_OP_CH_SEL_RGB, true, false, | ||
819 | ADV7604_OP_MODE_SEL_SDR_444 | ADV7604_OP_FORMAT_SEL_8BIT }, | ||
820 | { V4L2_MBUS_FMT_YUYV8_2X8, ADV7604_OP_CH_SEL_RGB, false, false, | ||
821 | ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_8BIT }, | ||
822 | { V4L2_MBUS_FMT_YVYU8_2X8, ADV7604_OP_CH_SEL_RGB, false, true, | ||
823 | ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_8BIT }, | ||
824 | { V4L2_MBUS_FMT_YUYV10_2X10, ADV7604_OP_CH_SEL_RGB, false, false, | ||
825 | ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_10BIT }, | ||
826 | { V4L2_MBUS_FMT_YVYU10_2X10, ADV7604_OP_CH_SEL_RGB, false, true, | ||
827 | ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_10BIT }, | ||
828 | { V4L2_MBUS_FMT_YUYV12_2X12, ADV7604_OP_CH_SEL_RGB, false, false, | ||
829 | ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_12BIT }, | ||
830 | { V4L2_MBUS_FMT_YVYU12_2X12, ADV7604_OP_CH_SEL_RGB, false, true, | ||
831 | ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_12BIT }, | ||
832 | { V4L2_MBUS_FMT_UYVY8_1X16, ADV7604_OP_CH_SEL_RBG, false, false, | ||
833 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT }, | ||
834 | { V4L2_MBUS_FMT_VYUY8_1X16, ADV7604_OP_CH_SEL_RBG, false, true, | ||
835 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT }, | ||
836 | { V4L2_MBUS_FMT_YUYV8_1X16, ADV7604_OP_CH_SEL_RGB, false, false, | ||
837 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT }, | ||
838 | { V4L2_MBUS_FMT_YVYU8_1X16, ADV7604_OP_CH_SEL_RGB, false, true, | ||
839 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT }, | ||
840 | { V4L2_MBUS_FMT_UYVY10_1X20, ADV7604_OP_CH_SEL_RBG, false, false, | ||
841 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_10BIT }, | ||
842 | { V4L2_MBUS_FMT_VYUY10_1X20, ADV7604_OP_CH_SEL_RBG, false, true, | ||
843 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_10BIT }, | ||
844 | { V4L2_MBUS_FMT_YUYV10_1X20, ADV7604_OP_CH_SEL_RGB, false, false, | ||
845 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_10BIT }, | ||
846 | { V4L2_MBUS_FMT_YVYU10_1X20, ADV7604_OP_CH_SEL_RGB, false, true, | ||
847 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_10BIT }, | ||
848 | { V4L2_MBUS_FMT_UYVY12_1X24, ADV7604_OP_CH_SEL_RBG, false, false, | ||
849 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT }, | ||
850 | { V4L2_MBUS_FMT_VYUY12_1X24, ADV7604_OP_CH_SEL_RBG, false, true, | ||
851 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT }, | ||
852 | { V4L2_MBUS_FMT_YUYV12_1X24, ADV7604_OP_CH_SEL_RGB, false, false, | ||
853 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT }, | ||
854 | { V4L2_MBUS_FMT_YVYU12_1X24, ADV7604_OP_CH_SEL_RGB, false, true, | ||
855 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT }, | ||
856 | }; | ||
857 | |||
858 | static const struct adv7604_format_info adv7611_formats[] = { | ||
859 | { V4L2_MBUS_FMT_RGB888_1X24, ADV7604_OP_CH_SEL_RGB, true, false, | ||
860 | ADV7604_OP_MODE_SEL_SDR_444 | ADV7604_OP_FORMAT_SEL_8BIT }, | ||
861 | { V4L2_MBUS_FMT_YUYV8_2X8, ADV7604_OP_CH_SEL_RGB, false, false, | ||
862 | ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_8BIT }, | ||
863 | { V4L2_MBUS_FMT_YVYU8_2X8, ADV7604_OP_CH_SEL_RGB, false, true, | ||
864 | ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_8BIT }, | ||
865 | { V4L2_MBUS_FMT_YUYV12_2X12, ADV7604_OP_CH_SEL_RGB, false, false, | ||
866 | ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_12BIT }, | ||
867 | { V4L2_MBUS_FMT_YVYU12_2X12, ADV7604_OP_CH_SEL_RGB, false, true, | ||
868 | ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_12BIT }, | ||
869 | { V4L2_MBUS_FMT_UYVY8_1X16, ADV7604_OP_CH_SEL_RBG, false, false, | ||
870 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT }, | ||
871 | { V4L2_MBUS_FMT_VYUY8_1X16, ADV7604_OP_CH_SEL_RBG, false, true, | ||
872 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT }, | ||
873 | { V4L2_MBUS_FMT_YUYV8_1X16, ADV7604_OP_CH_SEL_RGB, false, false, | ||
874 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT }, | ||
875 | { V4L2_MBUS_FMT_YVYU8_1X16, ADV7604_OP_CH_SEL_RGB, false, true, | ||
876 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT }, | ||
877 | { V4L2_MBUS_FMT_UYVY12_1X24, ADV7604_OP_CH_SEL_RBG, false, false, | ||
878 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT }, | ||
879 | { V4L2_MBUS_FMT_VYUY12_1X24, ADV7604_OP_CH_SEL_RBG, false, true, | ||
880 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT }, | ||
881 | { V4L2_MBUS_FMT_YUYV12_1X24, ADV7604_OP_CH_SEL_RGB, false, false, | ||
882 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT }, | ||
883 | { V4L2_MBUS_FMT_YVYU12_1X24, ADV7604_OP_CH_SEL_RGB, false, true, | ||
884 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT }, | ||
885 | }; | ||
886 | |||
887 | static const struct adv7604_format_info * | ||
888 | adv7604_format_info(struct adv7604_state *state, enum v4l2_mbus_pixelcode code) | ||
889 | { | ||
890 | unsigned int i; | ||
891 | |||
892 | for (i = 0; i < state->info->nformats; ++i) { | ||
893 | if (state->info->formats[i].code == code) | ||
894 | return &state->info->formats[i]; | ||
895 | } | ||
896 | |||
897 | return NULL; | ||
898 | } | ||
899 | |||
774 | /* ----------------------------------------------------------------------- */ | 900 | /* ----------------------------------------------------------------------- */ |
775 | 901 | ||
776 | static inline bool is_analog_input(struct v4l2_subdev *sd) | 902 | static inline bool is_analog_input(struct v4l2_subdev *sd) |
@@ -1720,29 +1846,132 @@ static int adv7604_s_routing(struct v4l2_subdev *sd, | |||
1720 | return 0; | 1846 | return 0; |
1721 | } | 1847 | } |
1722 | 1848 | ||
1723 | static int adv7604_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned int index, | 1849 | static int adv7604_enum_mbus_code(struct v4l2_subdev *sd, |
1724 | enum v4l2_mbus_pixelcode *code) | 1850 | struct v4l2_subdev_fh *fh, |
1851 | struct v4l2_subdev_mbus_code_enum *code) | ||
1725 | { | 1852 | { |
1726 | if (index) | 1853 | struct adv7604_state *state = to_state(sd); |
1854 | |||
1855 | if (code->index >= state->info->nformats) | ||
1727 | return -EINVAL; | 1856 | return -EINVAL; |
1728 | /* Good enough for now */ | 1857 | |
1729 | *code = V4L2_MBUS_FMT_FIXED; | 1858 | code->code = state->info->formats[code->index].code; |
1859 | |||
1730 | return 0; | 1860 | return 0; |
1731 | } | 1861 | } |
1732 | 1862 | ||
1733 | static int adv7604_g_mbus_fmt(struct v4l2_subdev *sd, | 1863 | static void adv7604_fill_format(struct adv7604_state *state, |
1734 | struct v4l2_mbus_framefmt *fmt) | 1864 | struct v4l2_mbus_framefmt *format) |
1735 | { | 1865 | { |
1736 | struct adv7604_state *state = to_state(sd); | 1866 | memset(format, 0, sizeof(*format)); |
1737 | 1867 | ||
1738 | fmt->width = state->timings.bt.width; | 1868 | format->width = state->timings.bt.width; |
1739 | fmt->height = state->timings.bt.height; | 1869 | format->height = state->timings.bt.height; |
1740 | fmt->code = V4L2_MBUS_FMT_FIXED; | 1870 | format->field = V4L2_FIELD_NONE; |
1741 | fmt->field = V4L2_FIELD_NONE; | 1871 | |
1742 | if (state->timings.bt.standards & V4L2_DV_BT_STD_CEA861) { | 1872 | if (state->timings.bt.standards & V4L2_DV_BT_STD_CEA861) |
1743 | fmt->colorspace = (state->timings.bt.height <= 576) ? | 1873 | format->colorspace = (state->timings.bt.height <= 576) ? |
1744 | V4L2_COLORSPACE_SMPTE170M : V4L2_COLORSPACE_REC709; | 1874 | V4L2_COLORSPACE_SMPTE170M : V4L2_COLORSPACE_REC709; |
1875 | } | ||
1876 | |||
1877 | /* | ||
1878 | * Compute the op_ch_sel value required to obtain on the bus the component order | ||
1879 | * corresponding to the selected format taking into account bus reordering | ||
1880 | * applied by the board at the output of the device. | ||
1881 | * | ||
1882 | * The following table gives the op_ch_value from the format component order | ||
1883 | * (expressed as op_ch_sel value in column) and the bus reordering (expressed as | ||
1884 | * adv7604_bus_order value in row). | ||
1885 | * | ||
1886 | * | GBR(0) GRB(1) BGR(2) RGB(3) BRG(4) RBG(5) | ||
1887 | * ----------+------------------------------------------------- | ||
1888 | * RGB (NOP) | GBR GRB BGR RGB BRG RBG | ||
1889 | * GRB (1-2) | BGR RGB GBR GRB RBG BRG | ||
1890 | * RBG (2-3) | GRB GBR BRG RBG BGR RGB | ||
1891 | * BGR (1-3) | RBG BRG RGB BGR GRB GBR | ||
1892 | * BRG (ROR) | BRG RBG GRB GBR RGB BGR | ||
1893 | * GBR (ROL) | RGB BGR RBG BRG GBR GRB | ||
1894 | */ | ||
1895 | static unsigned int adv7604_op_ch_sel(struct adv7604_state *state) | ||
1896 | { | ||
1897 | #define _SEL(a,b,c,d,e,f) { \ | ||
1898 | ADV7604_OP_CH_SEL_##a, ADV7604_OP_CH_SEL_##b, ADV7604_OP_CH_SEL_##c, \ | ||
1899 | ADV7604_OP_CH_SEL_##d, ADV7604_OP_CH_SEL_##e, ADV7604_OP_CH_SEL_##f } | ||
1900 | #define _BUS(x) [ADV7604_BUS_ORDER_##x] | ||
1901 | |||
1902 | static const unsigned int op_ch_sel[6][6] = { | ||
1903 | _BUS(RGB) /* NOP */ = _SEL(GBR, GRB, BGR, RGB, BRG, RBG), | ||
1904 | _BUS(GRB) /* 1-2 */ = _SEL(BGR, RGB, GBR, GRB, RBG, BRG), | ||
1905 | _BUS(RBG) /* 2-3 */ = _SEL(GRB, GBR, BRG, RBG, BGR, RGB), | ||
1906 | _BUS(BGR) /* 1-3 */ = _SEL(RBG, BRG, RGB, BGR, GRB, GBR), | ||
1907 | _BUS(BRG) /* ROR */ = _SEL(BRG, RBG, GRB, GBR, RGB, BGR), | ||
1908 | _BUS(GBR) /* ROL */ = _SEL(RGB, BGR, RBG, BRG, GBR, GRB), | ||
1909 | }; | ||
1910 | |||
1911 | return op_ch_sel[state->pdata.bus_order][state->format->op_ch_sel >> 5]; | ||
1912 | } | ||
1913 | |||
1914 | static void adv7604_setup_format(struct adv7604_state *state) | ||
1915 | { | ||
1916 | struct v4l2_subdev *sd = &state->sd; | ||
1917 | |||
1918 | io_write_and_or(sd, 0x02, 0xfd, | ||
1919 | state->format->rgb_out ? ADV7604_RGB_OUT : 0); | ||
1920 | io_write(sd, 0x03, state->format->op_format_sel | | ||
1921 | state->pdata.op_format_mode_sel); | ||
1922 | io_write_and_or(sd, 0x04, 0x1f, adv7604_op_ch_sel(state)); | ||
1923 | io_write_and_or(sd, 0x05, 0xfe, | ||
1924 | state->format->swap_cb_cr ? ADV7604_OP_SWAP_CB_CR : 0); | ||
1925 | } | ||
1926 | |||
1927 | static int adv7604_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | ||
1928 | struct v4l2_subdev_format *format) | ||
1929 | { | ||
1930 | struct adv7604_state *state = to_state(sd); | ||
1931 | |||
1932 | if (format->pad != state->source_pad) | ||
1933 | return -EINVAL; | ||
1934 | |||
1935 | adv7604_fill_format(state, &format->format); | ||
1936 | |||
1937 | if (format->which == V4L2_SUBDEV_FORMAT_TRY) { | ||
1938 | struct v4l2_mbus_framefmt *fmt; | ||
1939 | |||
1940 | fmt = v4l2_subdev_get_try_format(fh, format->pad); | ||
1941 | format->format.code = fmt->code; | ||
1942 | } else { | ||
1943 | format->format.code = state->format->code; | ||
1745 | } | 1944 | } |
1945 | |||
1946 | return 0; | ||
1947 | } | ||
1948 | |||
1949 | static int adv7604_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | ||
1950 | struct v4l2_subdev_format *format) | ||
1951 | { | ||
1952 | struct adv7604_state *state = to_state(sd); | ||
1953 | const struct adv7604_format_info *info; | ||
1954 | |||
1955 | if (format->pad != state->source_pad) | ||
1956 | return -EINVAL; | ||
1957 | |||
1958 | info = adv7604_format_info(state, format->format.code); | ||
1959 | if (info == NULL) | ||
1960 | info = adv7604_format_info(state, V4L2_MBUS_FMT_YUYV8_2X8); | ||
1961 | |||
1962 | adv7604_fill_format(state, &format->format); | ||
1963 | format->format.code = info->code; | ||
1964 | |||
1965 | if (format->which == V4L2_SUBDEV_FORMAT_TRY) { | ||
1966 | struct v4l2_mbus_framefmt *fmt; | ||
1967 | |||
1968 | fmt = v4l2_subdev_get_try_format(fh, format->pad); | ||
1969 | fmt->code = format->format.code; | ||
1970 | } else { | ||
1971 | state->format = info; | ||
1972 | adv7604_setup_format(state); | ||
1973 | } | ||
1974 | |||
1746 | return 0; | 1975 | return 0; |
1747 | } | 1976 | } |
1748 | 1977 | ||
@@ -2189,13 +2418,12 @@ static const struct v4l2_subdev_video_ops adv7604_video_ops = { | |||
2189 | .query_dv_timings = adv7604_query_dv_timings, | 2418 | .query_dv_timings = adv7604_query_dv_timings, |
2190 | .enum_dv_timings = adv7604_enum_dv_timings, | 2419 | .enum_dv_timings = adv7604_enum_dv_timings, |
2191 | .dv_timings_cap = adv7604_dv_timings_cap, | 2420 | .dv_timings_cap = adv7604_dv_timings_cap, |
2192 | .enum_mbus_fmt = adv7604_enum_mbus_fmt, | ||
2193 | .g_mbus_fmt = adv7604_g_mbus_fmt, | ||
2194 | .try_mbus_fmt = adv7604_g_mbus_fmt, | ||
2195 | .s_mbus_fmt = adv7604_g_mbus_fmt, | ||
2196 | }; | 2421 | }; |
2197 | 2422 | ||
2198 | static const struct v4l2_subdev_pad_ops adv7604_pad_ops = { | 2423 | static const struct v4l2_subdev_pad_ops adv7604_pad_ops = { |
2424 | .enum_mbus_code = adv7604_enum_mbus_code, | ||
2425 | .get_fmt = adv7604_get_format, | ||
2426 | .set_fmt = adv7604_set_format, | ||
2199 | .get_edid = adv7604_get_edid, | 2427 | .get_edid = adv7604_get_edid, |
2200 | .set_edid = adv7604_set_edid, | 2428 | .set_edid = adv7604_set_edid, |
2201 | }; | 2429 | }; |
@@ -2264,14 +2492,11 @@ static int adv7604_core_init(struct v4l2_subdev *sd) | |||
2264 | io_write_and_or(sd, 0x02, 0xf0, | 2492 | io_write_and_or(sd, 0x02, 0xf0, |
2265 | pdata->alt_gamma << 3 | | 2493 | pdata->alt_gamma << 3 | |
2266 | pdata->op_656_range << 2 | | 2494 | pdata->op_656_range << 2 | |
2267 | pdata->rgb_out << 1 | | ||
2268 | pdata->alt_data_sat << 0); | 2495 | pdata->alt_data_sat << 0); |
2269 | io_write(sd, 0x03, pdata->op_format_sel); | 2496 | io_write_and_or(sd, 0x05, 0xf1, pdata->blank_data << 3 | |
2270 | io_write_and_or(sd, 0x04, 0x1f, pdata->op_ch_sel << 5); | 2497 | pdata->insert_av_codes << 2 | |
2271 | io_write_and_or(sd, 0x05, 0xf0, pdata->blank_data << 3 | | 2498 | pdata->replicate_av_codes << 1); |
2272 | pdata->insert_av_codes << 2 | | 2499 | adv7604_setup_format(state); |
2273 | pdata->replicate_av_codes << 1 | | ||
2274 | pdata->invert_cbcr << 0); | ||
2275 | 2500 | ||
2276 | cp_write(sd, 0x69, 0x30); /* Enable CP CSC */ | 2501 | cp_write(sd, 0x69, 0x30); /* Enable CP CSC */ |
2277 | 2502 | ||
@@ -2439,6 +2664,8 @@ static const struct adv7604_chip_info adv7604_chip_info[] = { | |||
2439 | .tdms_lock_mask = 0xe0, | 2664 | .tdms_lock_mask = 0xe0, |
2440 | .cable_det_mask = 0x1e, | 2665 | .cable_det_mask = 0x1e, |
2441 | .fmt_change_digital_mask = 0xc1, | 2666 | .fmt_change_digital_mask = 0xc1, |
2667 | .formats = adv7604_formats, | ||
2668 | .nformats = ARRAY_SIZE(adv7604_formats), | ||
2442 | .set_termination = adv7604_set_termination, | 2669 | .set_termination = adv7604_set_termination, |
2443 | .setup_irqs = adv7604_setup_irqs, | 2670 | .setup_irqs = adv7604_setup_irqs, |
2444 | .read_hdmi_pixelclock = adv7604_read_hdmi_pixelclock, | 2671 | .read_hdmi_pixelclock = adv7604_read_hdmi_pixelclock, |
@@ -2470,6 +2697,8 @@ static const struct adv7604_chip_info adv7604_chip_info[] = { | |||
2470 | .tdms_lock_mask = 0x43, | 2697 | .tdms_lock_mask = 0x43, |
2471 | .cable_det_mask = 0x01, | 2698 | .cable_det_mask = 0x01, |
2472 | .fmt_change_digital_mask = 0x03, | 2699 | .fmt_change_digital_mask = 0x03, |
2700 | .formats = adv7611_formats, | ||
2701 | .nformats = ARRAY_SIZE(adv7611_formats), | ||
2473 | .set_termination = adv7611_set_termination, | 2702 | .set_termination = adv7611_set_termination, |
2474 | .setup_irqs = adv7611_setup_irqs, | 2703 | .setup_irqs = adv7611_setup_irqs, |
2475 | .read_hdmi_pixelclock = adv7611_read_hdmi_pixelclock, | 2704 | .read_hdmi_pixelclock = adv7611_read_hdmi_pixelclock, |
@@ -2525,6 +2754,7 @@ static int adv7604_probe(struct i2c_client *client, | |||
2525 | } | 2754 | } |
2526 | state->pdata = *pdata; | 2755 | state->pdata = *pdata; |
2527 | state->timings = cea640x480; | 2756 | state->timings = cea640x480; |
2757 | state->format = adv7604_format_info(state, V4L2_MBUS_FMT_YUYV8_2X8); | ||
2528 | 2758 | ||
2529 | sd = &state->sd; | 2759 | sd = &state->sd; |
2530 | v4l2_i2c_subdev_init(sd, client, &adv7604_ops); | 2760 | v4l2_i2c_subdev_init(sd, client, &adv7604_ops); |