aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2014-01-29 08:08:58 -0500
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-05-25 11:56:15 -0400
commitc784b1e2ece8a591263050d1f59607547dfad8f3 (patch)
tree718f6d67e21d1b7d6e739bae9652080428a93621 /drivers/media
parent454378923a9b44e26918893fac8bdeb43ae0f57b (diff)
[media] adv7604: Add sink pads
The ADV7604 has sink pads for its HDMI and analog inputs. Report them. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-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.c61
1 files changed, 35 insertions, 26 deletions
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index ca7590641581..79fb34d5ee2d 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -97,13 +97,15 @@ struct adv7604_chip_info {
97 * 97 *
98 ********************************************************************** 98 **********************************************************************
99 */ 99 */
100
100struct adv7604_state { 101struct adv7604_state {
101 const struct adv7604_chip_info *info; 102 const struct adv7604_chip_info *info;
102 struct adv7604_platform_data pdata; 103 struct adv7604_platform_data pdata;
103 struct v4l2_subdev sd; 104 struct v4l2_subdev sd;
104 struct media_pad pad; 105 struct media_pad pads[ADV7604_PAD_MAX];
106 unsigned int source_pad;
105 struct v4l2_ctrl_handler hdl; 107 struct v4l2_ctrl_handler hdl;
106 enum adv7604_input_port selected_input; 108 enum adv7604_pad selected_input;
107 struct v4l2_dv_timings timings; 109 struct v4l2_dv_timings timings;
108 struct { 110 struct {
109 u8 edid[256]; 111 u8 edid[256];
@@ -775,18 +777,18 @@ static inline bool is_analog_input(struct v4l2_subdev *sd)
775{ 777{
776 struct adv7604_state *state = to_state(sd); 778 struct adv7604_state *state = to_state(sd);
777 779
778 return state->selected_input == ADV7604_INPUT_VGA_RGB || 780 return state->selected_input == ADV7604_PAD_VGA_RGB ||
779 state->selected_input == ADV7604_INPUT_VGA_COMP; 781 state->selected_input == ADV7604_PAD_VGA_COMP;
780} 782}
781 783
782static inline bool is_digital_input(struct v4l2_subdev *sd) 784static inline bool is_digital_input(struct v4l2_subdev *sd)
783{ 785{
784 struct adv7604_state *state = to_state(sd); 786 struct adv7604_state *state = to_state(sd);
785 787
786 return state->selected_input == ADV7604_INPUT_HDMI_PORT_A || 788 return state->selected_input == ADV7604_PAD_HDMI_PORT_A ||
787 state->selected_input == ADV7604_INPUT_HDMI_PORT_B || 789 state->selected_input == ADV7604_PAD_HDMI_PORT_B ||
788 state->selected_input == ADV7604_INPUT_HDMI_PORT_C || 790 state->selected_input == ADV7604_PAD_HDMI_PORT_C ||
789 state->selected_input == ADV7604_INPUT_HDMI_PORT_D; 791 state->selected_input == ADV7604_PAD_HDMI_PORT_D;
790} 792}
791 793
792/* ----------------------------------------------------------------------- */ 794/* ----------------------------------------------------------------------- */
@@ -1066,14 +1068,14 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd)
1066 1068
1067 switch (state->rgb_quantization_range) { 1069 switch (state->rgb_quantization_range) {
1068 case V4L2_DV_RGB_RANGE_AUTO: 1070 case V4L2_DV_RGB_RANGE_AUTO:
1069 if (state->selected_input == ADV7604_INPUT_VGA_RGB) { 1071 if (state->selected_input == ADV7604_PAD_VGA_RGB) {
1070 /* Receiving analog RGB signal 1072 /* Receiving analog RGB signal
1071 * Set RGB full range (0-255) */ 1073 * Set RGB full range (0-255) */
1072 io_write_and_or(sd, 0x02, 0x0f, 0x10); 1074 io_write_and_or(sd, 0x02, 0x0f, 0x10);
1073 break; 1075 break;
1074 } 1076 }
1075 1077
1076 if (state->selected_input == ADV7604_INPUT_VGA_COMP) { 1078 if (state->selected_input == ADV7604_PAD_VGA_COMP) {
1077 /* Receiving analog YPbPr signal 1079 /* Receiving analog YPbPr signal
1078 * Set automode */ 1080 * Set automode */
1079 io_write_and_or(sd, 0x02, 0x0f, 0xf0); 1081 io_write_and_or(sd, 0x02, 0x0f, 0xf0);
@@ -1106,7 +1108,7 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd)
1106 } 1108 }
1107 break; 1109 break;
1108 case V4L2_DV_RGB_RANGE_LIMITED: 1110 case V4L2_DV_RGB_RANGE_LIMITED:
1109 if (state->selected_input == ADV7604_INPUT_VGA_COMP) { 1111 if (state->selected_input == ADV7604_PAD_VGA_COMP) {
1110 /* YCrCb limited range (16-235) */ 1112 /* YCrCb limited range (16-235) */
1111 io_write_and_or(sd, 0x02, 0x0f, 0x20); 1113 io_write_and_or(sd, 0x02, 0x0f, 0x20);
1112 break; 1114 break;
@@ -1117,7 +1119,7 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd)
1117 1119
1118 break; 1120 break;
1119 case V4L2_DV_RGB_RANGE_FULL: 1121 case V4L2_DV_RGB_RANGE_FULL:
1120 if (state->selected_input == ADV7604_INPUT_VGA_COMP) { 1122 if (state->selected_input == ADV7604_PAD_VGA_COMP) {
1121 /* YCrCb full range (0-255) */ 1123 /* YCrCb full range (0-255) */
1122 io_write_and_or(sd, 0x02, 0x0f, 0x60); 1124 io_write_and_or(sd, 0x02, 0x0f, 0x60);
1123 break; 1125 break;
@@ -1806,7 +1808,7 @@ static int adv7604_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
1806 struct adv7604_state *state = to_state(sd); 1808 struct adv7604_state *state = to_state(sd);
1807 u8 *data = NULL; 1809 u8 *data = NULL;
1808 1810
1809 if (edid->pad > ADV7604_EDID_PORT_D) 1811 if (edid->pad > ADV7604_PAD_HDMI_PORT_D)
1810 return -EINVAL; 1812 return -EINVAL;
1811 if (edid->blocks == 0) 1813 if (edid->blocks == 0)
1812 return -EINVAL; 1814 return -EINVAL;
@@ -1821,10 +1823,10 @@ static int adv7604_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
1821 edid->blocks = state->edid.blocks; 1823 edid->blocks = state->edid.blocks;
1822 1824
1823 switch (edid->pad) { 1825 switch (edid->pad) {
1824 case ADV7604_EDID_PORT_A: 1826 case ADV7604_PAD_HDMI_PORT_A:
1825 case ADV7604_EDID_PORT_B: 1827 case ADV7604_PAD_HDMI_PORT_B:
1826 case ADV7604_EDID_PORT_C: 1828 case ADV7604_PAD_HDMI_PORT_C:
1827 case ADV7604_EDID_PORT_D: 1829 case ADV7604_PAD_HDMI_PORT_D:
1828 if (state->edid.present & (1 << edid->pad)) 1830 if (state->edid.present & (1 << edid->pad))
1829 data = state->edid.edid; 1831 data = state->edid.edid;
1830 break; 1832 break;
@@ -1878,7 +1880,7 @@ static int adv7604_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
1878 int err; 1880 int err;
1879 int i; 1881 int i;
1880 1882
1881 if (edid->pad > ADV7604_EDID_PORT_D) 1883 if (edid->pad > ADV7604_PAD_HDMI_PORT_D)
1882 return -EINVAL; 1884 return -EINVAL;
1883 if (edid->start_block != 0) 1885 if (edid->start_block != 0)
1884 return -EINVAL; 1886 return -EINVAL;
@@ -1917,19 +1919,19 @@ static int adv7604_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
1917 spa_loc = 0xc0; /* Default value [REF_02, p. 116] */ 1919 spa_loc = 0xc0; /* Default value [REF_02, p. 116] */
1918 1920
1919 switch (edid->pad) { 1921 switch (edid->pad) {
1920 case ADV7604_EDID_PORT_A: 1922 case ADV7604_PAD_HDMI_PORT_A:
1921 state->spa_port_a[0] = edid->edid[spa_loc]; 1923 state->spa_port_a[0] = edid->edid[spa_loc];
1922 state->spa_port_a[1] = edid->edid[spa_loc + 1]; 1924 state->spa_port_a[1] = edid->edid[spa_loc + 1];
1923 break; 1925 break;
1924 case ADV7604_EDID_PORT_B: 1926 case ADV7604_PAD_HDMI_PORT_B:
1925 rep_write(sd, 0x70, edid->edid[spa_loc]); 1927 rep_write(sd, 0x70, edid->edid[spa_loc]);
1926 rep_write(sd, 0x71, edid->edid[spa_loc + 1]); 1928 rep_write(sd, 0x71, edid->edid[spa_loc + 1]);
1927 break; 1929 break;
1928 case ADV7604_EDID_PORT_C: 1930 case ADV7604_PAD_HDMI_PORT_C:
1929 rep_write(sd, 0x72, edid->edid[spa_loc]); 1931 rep_write(sd, 0x72, edid->edid[spa_loc]);
1930 rep_write(sd, 0x73, edid->edid[spa_loc + 1]); 1932 rep_write(sd, 0x73, edid->edid[spa_loc + 1]);
1931 break; 1933 break;
1932 case ADV7604_EDID_PORT_D: 1934 case ADV7604_PAD_HDMI_PORT_D:
1933 rep_write(sd, 0x74, edid->edid[spa_loc]); 1935 rep_write(sd, 0x74, edid->edid[spa_loc]);
1934 rep_write(sd, 0x75, edid->edid[spa_loc + 1]); 1936 rep_write(sd, 0x75, edid->edid[spa_loc + 1]);
1935 break; 1937 break;
@@ -2429,7 +2431,7 @@ static const struct adv7604_chip_info adv7604_chip_info[] = {
2429 [ADV7604] = { 2431 [ADV7604] = {
2430 .type = ADV7604, 2432 .type = ADV7604,
2431 .has_afe = true, 2433 .has_afe = true,
2432 .max_port = ADV7604_INPUT_VGA_COMP, 2434 .max_port = ADV7604_PAD_VGA_COMP,
2433 .num_dv_ports = 4, 2435 .num_dv_ports = 4,
2434 .edid_enable_reg = 0x77, 2436 .edid_enable_reg = 0x77,
2435 .edid_status_reg = 0x7d, 2437 .edid_status_reg = 0x7d,
@@ -2460,7 +2462,7 @@ static const struct adv7604_chip_info adv7604_chip_info[] = {
2460 [ADV7611] = { 2462 [ADV7611] = {
2461 .type = ADV7611, 2463 .type = ADV7611,
2462 .has_afe = false, 2464 .has_afe = false,
2463 .max_port = ADV7604_INPUT_HDMI_PORT_A, 2465 .max_port = ADV7604_PAD_HDMI_PORT_A,
2464 .num_dv_ports = 1, 2466 .num_dv_ports = 1,
2465 .edid_enable_reg = 0x74, 2467 .edid_enable_reg = 0x74,
2466 .edid_status_reg = 0x76, 2468 .edid_status_reg = 0x76,
@@ -2494,6 +2496,7 @@ static int adv7604_probe(struct i2c_client *client,
2494 struct adv7604_platform_data *pdata = client->dev.platform_data; 2496 struct adv7604_platform_data *pdata = client->dev.platform_data;
2495 struct v4l2_ctrl_handler *hdl; 2497 struct v4l2_ctrl_handler *hdl;
2496 struct v4l2_subdev *sd; 2498 struct v4l2_subdev *sd;
2499 unsigned int i;
2497 u16 val; 2500 u16 val;
2498 int err; 2501 int err;
2499 2502
@@ -2639,8 +2642,14 @@ static int adv7604_probe(struct i2c_client *client,
2639 INIT_DELAYED_WORK(&state->delayed_work_enable_hotplug, 2642 INIT_DELAYED_WORK(&state->delayed_work_enable_hotplug,
2640 adv7604_delayed_work_enable_hotplug); 2643 adv7604_delayed_work_enable_hotplug);
2641 2644
2642 state->pad.flags = MEDIA_PAD_FL_SOURCE; 2645 state->source_pad = state->info->num_dv_ports
2643 err = media_entity_init(&sd->entity, 1, &state->pad, 0); 2646 + (state->info->has_afe ? 2 : 0);
2647 for (i = 0; i < state->source_pad; ++i)
2648 state->pads[i].flags = MEDIA_PAD_FL_SINK;
2649 state->pads[state->source_pad].flags = MEDIA_PAD_FL_SOURCE;
2650
2651 err = media_entity_init(&sd->entity, state->source_pad + 1,
2652 state->pads, 0);
2644 if (err) 2653 if (err)
2645 goto err_work_queues; 2654 goto err_work_queues;
2646 2655