Skip to content

Commit

Permalink
[media] adv7604: Add DT support
Browse files Browse the repository at this point in the history
Parse the device tree node to populate platform data. Only the ADV7611
is currently support with DT.

Signed-off-by: Laurent Pinchart <[email protected]>
Acked-by: Hans Verkuil <[email protected]>
Acked-by: Sylwester Nawrocki <[email protected]>
Signed-off-by: Mauro Carvalho Chehab <[email protected]>
  • Loading branch information
pinchartl authored and mchehab committed May 25, 2014
1 parent 5ef54b5 commit f82f313
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 14 deletions.
57 changes: 57 additions & 0 deletions Documentation/devicetree/bindings/media/i2c/adv7604.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
* Analog Devices ADV7604/11 video decoder with HDMI receiver

The ADV7604 and ADV7611 are multiformat video decoders with an integrated HDMI
receiver. The ADV7604 has four multiplexed HDMI inputs and one analog input,
and the ADV7611 has one HDMI input and no analog input.

These device tree bindings support the ADV7611 only at the moment.

Required Properties:

- compatible: Must contain one of the following
- "adi,adv7611" for the ADV7611

- reg: I2C slave address

- hpd-gpios: References to the GPIOs that control the HDMI hot-plug
detection pins, one per HDMI input. The active flag indicates the GPIO
level that enables hot-plug detection.

The device node must contain one 'port' child node per device input and output
port, in accordance with the video interface bindings defined in
Documentation/devicetree/bindings/media/video-interfaces.txt. The port nodes
are numbered as follows.

Port ADV7611
------------------------------------------------------------
HDMI 0
Digital output 1

The digital output port node must contain at least one endpoint.

Optional Properties:

- reset-gpios: Reference to the GPIO connected to the device's reset pin.

Example:

hdmi_receiver@4c {
compatible = "adi,adv7611";
reg = <0x4c>;

reset-gpios = <&ioexp 0 GPIO_ACTIVE_LOW>;
hpd-gpios = <&ioexp 2 GPIO_ACTIVE_HIGH>;

#address-cells = <1>;
#size-cells = <0>;

port@0 {
reg = <0>;
};
port@1 {
reg = <1>;
hdmi_in: endpoint {
remote-endpoint = <&ccdc_in>;
};
};
};
80 changes: 66 additions & 14 deletions drivers/media/i2c/adv7604.c
Original file line number Diff line number Diff line change
Expand Up @@ -2663,13 +2663,58 @@ static const struct adv7604_chip_info adv7604_chip_info[] = {
},
};

static struct i2c_device_id adv7604_i2c_id[] = {
{ "adv7604", (kernel_ulong_t)&adv7604_chip_info[ADV7604] },
{ "adv7611", (kernel_ulong_t)&adv7604_chip_info[ADV7611] },
{ }
};
MODULE_DEVICE_TABLE(i2c, adv7604_i2c_id);

static struct of_device_id adv7604_of_id[] __maybe_unused = {
{ .compatible = "adi,adv7611", .data = &adv7604_chip_info[ADV7611] },
{ }
};
MODULE_DEVICE_TABLE(of, adv7604_of_id);

static int adv7604_parse_dt(struct adv7604_state *state)
{
/* Disable the interrupt for now as no DT-based board uses it. */
state->pdata.int1_config = ADV7604_INT1_CONFIG_DISABLED;

/* Use the default I2C addresses. */
state->pdata.i2c_addresses[ADV7604_PAGE_AVLINK] = 0x42;
state->pdata.i2c_addresses[ADV7604_PAGE_CEC] = 0x40;
state->pdata.i2c_addresses[ADV7604_PAGE_INFOFRAME] = 0x3e;
state->pdata.i2c_addresses[ADV7604_PAGE_ESDP] = 0x38;
state->pdata.i2c_addresses[ADV7604_PAGE_DPP] = 0x3c;
state->pdata.i2c_addresses[ADV7604_PAGE_AFE] = 0x26;
state->pdata.i2c_addresses[ADV7604_PAGE_REP] = 0x32;
state->pdata.i2c_addresses[ADV7604_PAGE_EDID] = 0x36;
state->pdata.i2c_addresses[ADV7604_PAGE_HDMI] = 0x34;
state->pdata.i2c_addresses[ADV7604_PAGE_TEST] = 0x30;
state->pdata.i2c_addresses[ADV7604_PAGE_CP] = 0x22;
state->pdata.i2c_addresses[ADV7604_PAGE_VDP] = 0x24;

/* Hardcode the remaining platform data fields. */
state->pdata.disable_pwrdnb = 0;
state->pdata.disable_cable_det_rst = 0;
state->pdata.default_input = -1;
state->pdata.blank_data = 1;
state->pdata.op_656_range = 1;
state->pdata.alt_data_sat = 1;
state->pdata.insert_av_codes = 1;
state->pdata.op_format_mode_sel = ADV7604_OP_FORMAT_MODE0;
state->pdata.bus_order = ADV7604_BUS_ORDER_RGB;

return 0;
}

static int adv7604_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
static const struct v4l2_dv_timings cea640x480 =
V4L2_DV_BT_CEA_640X480P59_94;
struct adv7604_state *state;
struct adv7604_platform_data *pdata = client->dev.platform_data;
struct v4l2_ctrl_handler *hdl;
struct v4l2_subdev *sd;
unsigned int i;
Expand All @@ -2688,19 +2733,32 @@ static int adv7604_probe(struct i2c_client *client,
return -ENOMEM;
}

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

/* initialize variables */
state->restart_stdi_once = true;
state->selected_input = ~0;

/* platform data */
if (!pdata) {
if (IS_ENABLED(CONFIG_OF) && client->dev.of_node) {
const struct of_device_id *oid;

oid = of_match_node(adv7604_of_id, client->dev.of_node);
state->info = oid->data;

err = adv7604_parse_dt(state);
if (err < 0) {
v4l_err(client, "DT parsing error\n");
return err;
}
} else if (client->dev.platform_data) {
struct adv7604_platform_data *pdata = client->dev.platform_data;

state->info = (const struct adv7604_chip_info *)id->driver_data;
state->pdata = *pdata;
} else {
v4l_err(client, "No platform data!\n");
return -ENODEV;
}
state->pdata = *pdata;

/* Request GPIOs. */
for (i = 0; i < state->info->num_dv_ports; ++i) {
Expand Down Expand Up @@ -2799,7 +2857,7 @@ static int adv7604_probe(struct i2c_client *client,
continue;

state->i2c_clients[i] =
adv7604_dummy_client(sd, pdata->i2c_addresses[i],
adv7604_dummy_client(sd, state->pdata.i2c_addresses[i],
0xf2 + i);
if (state->i2c_clients[i] == NULL) {
err = -ENOMEM;
Expand Down Expand Up @@ -2873,21 +2931,15 @@ static int adv7604_remove(struct i2c_client *client)

/* ----------------------------------------------------------------------- */

static struct i2c_device_id adv7604_id[] = {
{ "adv7604", ADV7604 },
{ "adv7611", ADV7611 },
{ }
};
MODULE_DEVICE_TABLE(i2c, adv7604_id);

static struct i2c_driver adv7604_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "adv7604",
.of_match_table = of_match_ptr(adv7604_of_id),
},
.probe = adv7604_probe,
.remove = adv7604_remove,
.id_table = adv7604_id,
.id_table = adv7604_i2c_id,
};

module_i2c_driver(adv7604_driver);

0 comments on commit f82f313

Please sign in to comment.