Skip to content

Commit 0e158be

Browse files
pinchartlMichal Simek
authored andcommitted
adv7604: Add DT support
Parse the device tree node to populate platform data. Signed-off-by: Laurent Pinchart <[email protected]> Acked-by: Hans Verkuil <[email protected]>
1 parent 183c3f7 commit 0e158be

File tree

2 files changed

+135
-14
lines changed

2 files changed

+135
-14
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
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+
Required Properties:
8+
9+
- compatible: Must contain one of the following
10+
- "adi,adv7604" for the ADV7604
11+
- "adi,adv7611" for the ADV7611
12+
13+
- reg: I2C slave address
14+
15+
- hpd-gpios: References to the GPIOs that control the HDMI hot-plug
16+
detection pins, one per HDMI input. The active flag indicates the GPIO
17+
level that enables hot-plug detection.
18+
19+
Optional Properties:
20+
21+
- reset-gpios: Reference to the GPIO connected to the device's reset pin.
22+
23+
- adi,default-input: Index of the input to be configured as default. Valid
24+
values are 0..5 for the ADV7604 and 0 for the ADV7611.
25+
26+
- adi,disable-power-down: Boolean property. When set forces the device to
27+
ignore the power-down pin. The property is valid for the ADV7604 only as
28+
the ADV7611 has no power-down pin.
29+
30+
- adi,disable-cable-reset: Boolean property. When set disables the HDMI
31+
receiver automatic reset when the HDMI cable is unplugged.
32+
33+
Example:
34+
35+
hdmi_receiver@4c {
36+
compatible = "adi,adv7611";
37+
reg = <0x4c>;
38+
39+
reset-gpios = <&ioexp 0 GPIO_ACTIVE_LOW>;
40+
hpd-gpios = <&ioexp 2 GPIO_ACTIVE_HIGH>;
41+
42+
adi,default-input = <0>;
43+
44+
#address-cells = <1>;
45+
#size-cells = <0>;
46+
47+
port@0 {
48+
reg = <0>;
49+
};
50+
port@1 {
51+
reg = <1>;
52+
hdmi_in: endpoint {
53+
remote-endpoint = <&ccdc_in>;
54+
};
55+
};
56+
};

drivers/media/i2c/adv7604.c

Lines changed: 79 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2663,13 +2663,71 @@ static const struct adv7604_chip_info adv7604_chip_info[] = {
26632663
},
26642664
};
26652665

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[] = {
2674+
{ .compatible = "adi,adv7604", .data = &adv7604_chip_info[ADV7604] },
2675+
{ .compatible = "adi,adv7611", .data = &adv7604_chip_info[ADV7611] },
2676+
{ }
2677+
};
2678+
MODULE_DEVICE_TABLE(of, adv7604_of_id);
2679+
2680+
static int adv7604_parse_dt(struct adv7604_state *state)
2681+
{
2682+
struct device_node *np;
2683+
int ret;
2684+
2685+
np = state->i2c_clients[ADV7604_PAGE_IO]->dev.of_node;
2686+
2687+
state->pdata.disable_pwrdnb =
2688+
of_property_read_bool(np, "adi,disable-power-down");
2689+
state->pdata.disable_cable_det_rst =
2690+
of_property_read_bool(np, "adi,disable-cable-reset");
2691+
2692+
ret = of_property_read_u32(np, "adi,default-input",
2693+
&state->pdata.default_input);
2694+
if (ret < 0)
2695+
state->pdata.default_input = -1;
2696+
2697+
/* Disable the interrupt for now as no DT-based board uses it. */
2698+
state->pdata.int1_config = ADV7604_INT1_CONFIG_DISABLED;
2699+
2700+
/* Use the default I2C addresses. */
2701+
state->pdata.i2c_addresses[ADV7604_PAGE_AVLINK] = 0x42;
2702+
state->pdata.i2c_addresses[ADV7604_PAGE_CEC] = 0x40;
2703+
state->pdata.i2c_addresses[ADV7604_PAGE_INFOFRAME] = 0x3e;
2704+
state->pdata.i2c_addresses[ADV7604_PAGE_ESDP] = 0x38;
2705+
state->pdata.i2c_addresses[ADV7604_PAGE_DPP] = 0x3c;
2706+
state->pdata.i2c_addresses[ADV7604_PAGE_AFE] = 0x26;
2707+
state->pdata.i2c_addresses[ADV7604_PAGE_REP] = 0x32;
2708+
state->pdata.i2c_addresses[ADV7604_PAGE_EDID] = 0x36;
2709+
state->pdata.i2c_addresses[ADV7604_PAGE_HDMI] = 0x34;
2710+
state->pdata.i2c_addresses[ADV7604_PAGE_TEST] = 0x30;
2711+
state->pdata.i2c_addresses[ADV7604_PAGE_CP] = 0x22;
2712+
state->pdata.i2c_addresses[ADV7604_PAGE_VDP] = 0x24;
2713+
2714+
/* HACK: Hardcode the remaining platform data fields. */
2715+
state->pdata.blank_data = 1;
2716+
state->pdata.op_656_range = 1;
2717+
state->pdata.alt_data_sat = 1;
2718+
state->pdata.insert_av_codes = 1;
2719+
state->pdata.op_format_mode_sel = ADV7604_OP_FORMAT_MODE0;
2720+
state->pdata.bus_order = ADV7604_BUS_ORDER_RGB;
2721+
2722+
return 0;
2723+
}
2724+
26662725
static int adv7604_probe(struct i2c_client *client,
26672726
const struct i2c_device_id *id)
26682727
{
26692728
static const struct v4l2_dv_timings cea640x480 =
26702729
V4L2_DV_BT_CEA_640X480P59_94;
26712730
struct adv7604_state *state;
2672-
struct adv7604_platform_data *pdata = client->dev.platform_data;
26732731
struct v4l2_ctrl_handler *hdl;
26742732
struct v4l2_subdev *sd;
26752733
unsigned int i;
@@ -2688,19 +2746,32 @@ static int adv7604_probe(struct i2c_client *client,
26882746
return -ENOMEM;
26892747
}
26902748

2691-
state->info = &adv7604_chip_info[id->driver_data];
26922749
state->i2c_clients[ADV7604_PAGE_IO] = client;
26932750

26942751
/* initialize variables */
26952752
state->restart_stdi_once = true;
26962753
state->selected_input = ~0;
26972754

2698-
/* platform data */
2699-
if (!pdata) {
2755+
if (IS_ENABLED(CONFIG_OF) && client->dev.of_node) {
2756+
const struct of_device_id *oid;
2757+
2758+
oid = of_match_node(adv7604_of_id, client->dev.of_node);
2759+
state->info = oid->data;
2760+
2761+
err = adv7604_parse_dt(state);
2762+
if (err < 0) {
2763+
v4l_err(client, "DT parsing error\n");
2764+
return err;
2765+
}
2766+
} else if (client->dev.platform_data) {
2767+
struct adv7604_platform_data *pdata = client->dev.platform_data;
2768+
2769+
state->info = (const struct adv7604_chip_info *)id->driver_data;
2770+
state->pdata = *pdata;
2771+
} else {
27002772
v4l_err(client, "No platform data!\n");
27012773
return -ENODEV;
27022774
}
2703-
state->pdata = *pdata;
27042775

27052776
/* Request GPIOs. */
27062777
for (i = 0; i < state->info->num_dv_ports; ++i) {
@@ -2799,7 +2870,7 @@ static int adv7604_probe(struct i2c_client *client,
27992870
continue;
28002871

28012872
state->i2c_clients[i] =
2802-
adv7604_dummy_client(sd, pdata->i2c_addresses[i],
2873+
adv7604_dummy_client(sd, state->pdata.i2c_addresses[i],
28032874
0xf2 + i);
28042875
if (state->i2c_clients[i] == NULL) {
28052876
err = -ENOMEM;
@@ -2873,21 +2944,15 @@ static int adv7604_remove(struct i2c_client *client)
28732944

28742945
/* ----------------------------------------------------------------------- */
28752946

2876-
static struct i2c_device_id adv7604_id[] = {
2877-
{ "adv7604", ADV7604 },
2878-
{ "adv7611", ADV7611 },
2879-
{ }
2880-
};
2881-
MODULE_DEVICE_TABLE(i2c, adv7604_id);
2882-
28832947
static struct i2c_driver adv7604_driver = {
28842948
.driver = {
28852949
.owner = THIS_MODULE,
28862950
.name = "adv7604",
2951+
.of_match_table = of_match_ptr(adv7604_of_id),
28872952
},
28882953
.probe = adv7604_probe,
28892954
.remove = adv7604_remove,
2890-
.id_table = adv7604_id,
2955+
.id_table = adv7604_i2c_id,
28912956
};
28922957

28932958
module_i2c_driver(adv7604_driver);

0 commit comments

Comments
 (0)