diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2013-11-25 14:19:08 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-05-25 12:04:00 -0400 |
commit | f82f313e9739026ca96342b5b44c5c94072e166a (patch) | |
tree | 135a6deb589d3540298d46aef7665af5f0d9566c | |
parent | 5ef54b5955acdcc63ac8ad7cf0aef3d16070773a (diff) |
[media] adv7604: Add DT support
Parse the device tree node to populate platform data. Only the ADV7611
is currently support with DT.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Acked-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
-rw-r--r-- | Documentation/devicetree/bindings/media/i2c/adv7604.txt | 57 | ||||
-rw-r--r-- | drivers/media/i2c/adv7604.c | 80 |
2 files changed, 123 insertions, 14 deletions
diff --git a/Documentation/devicetree/bindings/media/i2c/adv7604.txt b/Documentation/devicetree/bindings/media/i2c/adv7604.txt new file mode 100644 index 000000000000..2efb48f20fb6 --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/adv7604.txt | |||
@@ -0,0 +1,57 @@ | |||
1 | * Analog Devices ADV7604/11 video decoder with HDMI receiver | ||
2 | |||
3 | The ADV7604 and ADV7611 are multiformat video decoders with an integrated HDMI | ||
4 | receiver. The ADV7604 has four multiplexed HDMI inputs and one analog input, | ||
5 | and the ADV7611 has one HDMI input and no analog input. | ||
6 | |||
7 | These device tree bindings support the ADV7611 only at the moment. | ||
8 | |||
9 | Required Properties: | ||
10 | |||
11 | - compatible: Must contain one of the following | ||
12 | - "adi,adv7611" for the ADV7611 | ||
13 | |||
14 | - reg: I2C slave address | ||
15 | |||
16 | - hpd-gpios: References to the GPIOs that control the HDMI hot-plug | ||
17 | detection pins, one per HDMI input. The active flag indicates the GPIO | ||
18 | level that enables hot-plug detection. | ||
19 | |||
20 | The device node must contain one 'port' child node per device input and output | ||
21 | port, in accordance with the video interface bindings defined in | ||
22 | Documentation/devicetree/bindings/media/video-interfaces.txt. The port nodes | ||
23 | are numbered as follows. | ||
24 | |||
25 | Port ADV7611 | ||
26 | ------------------------------------------------------------ | ||
27 | HDMI 0 | ||
28 | Digital output 1 | ||
29 | |||
30 | The digital output port node must contain at least one endpoint. | ||
31 | |||
32 | Optional Properties: | ||
33 | |||
34 | - reset-gpios: Reference to the GPIO connected to the device's reset pin. | ||
35 | |||
36 | Example: | ||
37 | |||
38 | hdmi_receiver@4c { | ||
39 | compatible = "adi,adv7611"; | ||
40 | reg = <0x4c>; | ||
41 | |||
42 | reset-gpios = <&ioexp 0 GPIO_ACTIVE_LOW>; | ||
43 | hpd-gpios = <&ioexp 2 GPIO_ACTIVE_HIGH>; | ||
44 | |||
45 | #address-cells = <1>; | ||
46 | #size-cells = <0>; | ||
47 | |||
48 | port@0 { | ||
49 | reg = <0>; | ||
50 | }; | ||
51 | port@1 { | ||
52 | reg = <1>; | ||
53 | hdmi_in: endpoint { | ||
54 | remote-endpoint = <&ccdc_in>; | ||
55 | }; | ||
56 | }; | ||
57 | }; | ||
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index 342d73d3989b..1323189a45fa 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c | |||
@@ -2663,13 +2663,58 @@ static const struct adv7604_chip_info adv7604_chip_info[] = { | |||
2663 | }, | 2663 | }, |
2664 | }; | 2664 | }; |
2665 | 2665 | ||
2666 | static struct i2c_device_id adv7604_i2c_id[] = { | ||
2667 | { "adv7604", (kernel_ulong_t)&adv7604_chip_info[ADV7604] }, | ||
2668 | { "adv7611", (kernel_ulong_t)&adv7604_chip_info[ADV7611] }, | ||
2669 | { } | ||
2670 | }; | ||
2671 | MODULE_DEVICE_TABLE(i2c, adv7604_i2c_id); | ||
2672 | |||
2673 | static struct of_device_id adv7604_of_id[] __maybe_unused = { | ||
2674 | { .compatible = "adi,adv7611", .data = &adv7604_chip_info[ADV7611] }, | ||
2675 | { } | ||
2676 | }; | ||
2677 | MODULE_DEVICE_TABLE(of, adv7604_of_id); | ||
2678 | |||
2679 | static int adv7604_parse_dt(struct adv7604_state *state) | ||
2680 | { | ||
2681 | /* Disable the interrupt for now as no DT-based board uses it. */ | ||
2682 | state->pdata.int1_config = ADV7604_INT1_CONFIG_DISABLED; | ||
2683 | |||
2684 | /* Use the default I2C addresses. */ | ||
2685 | state->pdata.i2c_addresses[ADV7604_PAGE_AVLINK] = 0x42; | ||
2686 | state->pdata.i2c_addresses[ADV7604_PAGE_CEC] = 0x40; | ||
2687 | state->pdata.i2c_addresses[ADV7604_PAGE_INFOFRAME] = 0x3e; | ||
2688 | state->pdata.i2c_addresses[ADV7604_PAGE_ESDP] = 0x38; | ||
2689 | state->pdata.i2c_addresses[ADV7604_PAGE_DPP] = 0x3c; | ||
2690 | state->pdata.i2c_addresses[ADV7604_PAGE_AFE] = 0x26; | ||
2691 | state->pdata.i2c_addresses[ADV7604_PAGE_REP] = 0x32; | ||
2692 | state->pdata.i2c_addresses[ADV7604_PAGE_EDID] = 0x36; | ||
2693 | state->pdata.i2c_addresses[ADV7604_PAGE_HDMI] = 0x34; | ||
2694 | state->pdata.i2c_addresses[ADV7604_PAGE_TEST] = 0x30; | ||
2695 | state->pdata.i2c_addresses[ADV7604_PAGE_CP] = 0x22; | ||
2696 | state->pdata.i2c_addresses[ADV7604_PAGE_VDP] = 0x24; | ||
2697 | |||
2698 | /* Hardcode the remaining platform data fields. */ | ||
2699 | state->pdata.disable_pwrdnb = 0; | ||
2700 | state->pdata.disable_cable_det_rst = 0; | ||
2701 | state->pdata.default_input = -1; | ||
2702 | state->pdata.blank_data = 1; | ||
2703 | state->pdata.op_656_range = 1; | ||
2704 | state->pdata.alt_data_sat = 1; | ||
2705 | state->pdata.insert_av_codes = 1; | ||
2706 | state->pdata.op_format_mode_sel = ADV7604_OP_FORMAT_MODE0; | ||
2707 | state->pdata.bus_order = ADV7604_BUS_ORDER_RGB; | ||
2708 | |||
2709 | return 0; | ||
2710 | } | ||
2711 | |||
2666 | static int adv7604_probe(struct i2c_client *client, | 2712 | static int adv7604_probe(struct i2c_client *client, |
2667 | const struct i2c_device_id *id) | 2713 | const struct i2c_device_id *id) |
2668 | { | 2714 | { |
2669 | static const struct v4l2_dv_timings cea640x480 = | 2715 | static const struct v4l2_dv_timings cea640x480 = |
2670 | V4L2_DV_BT_CEA_640X480P59_94; | 2716 | V4L2_DV_BT_CEA_640X480P59_94; |
2671 | struct adv7604_state *state; | 2717 | struct adv7604_state *state; |
2672 | struct adv7604_platform_data *pdata = client->dev.platform_data; | ||
2673 | struct v4l2_ctrl_handler *hdl; | 2718 | struct v4l2_ctrl_handler *hdl; |
2674 | struct v4l2_subdev *sd; | 2719 | struct v4l2_subdev *sd; |
2675 | unsigned int i; | 2720 | unsigned int i; |
@@ -2688,19 +2733,32 @@ static int adv7604_probe(struct i2c_client *client, | |||
2688 | return -ENOMEM; | 2733 | return -ENOMEM; |
2689 | } | 2734 | } |
2690 | 2735 | ||
2691 | state->info = &adv7604_chip_info[id->driver_data]; | ||
2692 | state->i2c_clients[ADV7604_PAGE_IO] = client; | 2736 | state->i2c_clients[ADV7604_PAGE_IO] = client; |
2693 | 2737 | ||
2694 | /* initialize variables */ | 2738 | /* initialize variables */ |
2695 | state->restart_stdi_once = true; | 2739 | state->restart_stdi_once = true; |
2696 | state->selected_input = ~0; | 2740 | state->selected_input = ~0; |
2697 | 2741 | ||
2698 | /* platform data */ | 2742 | if (IS_ENABLED(CONFIG_OF) && client->dev.of_node) { |
2699 | if (!pdata) { | 2743 | const struct of_device_id *oid; |
2744 | |||
2745 | oid = of_match_node(adv7604_of_id, client->dev.of_node); | ||
2746 | state->info = oid->data; | ||
2747 | |||
2748 | err = adv7604_parse_dt(state); | ||
2749 | if (err < 0) { | ||
2750 | v4l_err(client, "DT parsing error\n"); | ||
2751 | return err; | ||
2752 | } | ||
2753 | } else if (client->dev.platform_data) { | ||
2754 | struct adv7604_platform_data *pdata = client->dev.platform_data; | ||
2755 | |||
2756 | state->info = (const struct adv7604_chip_info *)id->driver_data; | ||
2757 | state->pdata = *pdata; | ||
2758 | } else { | ||
2700 | v4l_err(client, "No platform data!\n"); | 2759 | v4l_err(client, "No platform data!\n"); |
2701 | return -ENODEV; | 2760 | return -ENODEV; |
2702 | } | 2761 | } |
2703 | state->pdata = *pdata; | ||
2704 | 2762 | ||
2705 | /* Request GPIOs. */ | 2763 | /* Request GPIOs. */ |
2706 | for (i = 0; i < state->info->num_dv_ports; ++i) { | 2764 | for (i = 0; i < state->info->num_dv_ports; ++i) { |
@@ -2799,7 +2857,7 @@ static int adv7604_probe(struct i2c_client *client, | |||
2799 | continue; | 2857 | continue; |
2800 | 2858 | ||
2801 | state->i2c_clients[i] = | 2859 | state->i2c_clients[i] = |
2802 | adv7604_dummy_client(sd, pdata->i2c_addresses[i], | 2860 | adv7604_dummy_client(sd, state->pdata.i2c_addresses[i], |
2803 | 0xf2 + i); | 2861 | 0xf2 + i); |
2804 | if (state->i2c_clients[i] == NULL) { | 2862 | if (state->i2c_clients[i] == NULL) { |
2805 | err = -ENOMEM; | 2863 | err = -ENOMEM; |
@@ -2873,21 +2931,15 @@ static int adv7604_remove(struct i2c_client *client) | |||
2873 | 2931 | ||
2874 | /* ----------------------------------------------------------------------- */ | 2932 | /* ----------------------------------------------------------------------- */ |
2875 | 2933 | ||
2876 | static struct i2c_device_id adv7604_id[] = { | ||
2877 | { "adv7604", ADV7604 }, | ||
2878 | { "adv7611", ADV7611 }, | ||
2879 | { } | ||
2880 | }; | ||
2881 | MODULE_DEVICE_TABLE(i2c, adv7604_id); | ||
2882 | |||
2883 | static struct i2c_driver adv7604_driver = { | 2934 | static struct i2c_driver adv7604_driver = { |
2884 | .driver = { | 2935 | .driver = { |
2885 | .owner = THIS_MODULE, | 2936 | .owner = THIS_MODULE, |
2886 | .name = "adv7604", | 2937 | .name = "adv7604", |
2938 | .of_match_table = of_match_ptr(adv7604_of_id), | ||
2887 | }, | 2939 | }, |
2888 | .probe = adv7604_probe, | 2940 | .probe = adv7604_probe, |
2889 | .remove = adv7604_remove, | 2941 | .remove = adv7604_remove, |
2890 | .id_table = adv7604_id, | 2942 | .id_table = adv7604_i2c_id, |
2891 | }; | 2943 | }; |
2892 | 2944 | ||
2893 | module_i2c_driver(adv7604_driver); | 2945 | module_i2c_driver(adv7604_driver); |