aboutsummaryrefslogtreecommitdiff
path: root/drivers/media/i2c/adv748x
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/i2c/adv748x')
-rw-r--r--drivers/media/i2c/adv748x/adv748x-afe.c6
-rw-r--r--drivers/media/i2c/adv748x/adv748x-core.c34
-rw-r--r--drivers/media/i2c/adv748x/adv748x-csi2.c6
-rw-r--r--drivers/media/i2c/adv748x/adv748x.h2
4 files changed, 33 insertions, 15 deletions
diff --git a/drivers/media/i2c/adv748x/adv748x-afe.c b/drivers/media/i2c/adv748x/adv748x-afe.c
index dbbb1e4d6363..4052cf67bf16 100644
--- a/drivers/media/i2c/adv748x/adv748x-afe.c
+++ b/drivers/media/i2c/adv748x/adv748x-afe.c
@@ -154,7 +154,7 @@ static void adv748x_afe_set_video_standard(struct adv748x_state *state,
(sdpstd & 0xf) << ADV748X_SDP_VID_SEL_SHIFT);
}
-static int adv748x_afe_s_input(struct adv748x_afe *afe, unsigned int input)
+int adv748x_afe_s_input(struct adv748x_afe *afe, unsigned int input)
{
struct adv748x_state *state = adv748x_afe_to_state(afe);
@@ -520,10 +520,6 @@ int adv748x_afe_init(struct adv748x_afe *afe)
}
}
- adv748x_afe_s_input(afe, afe->input);
-
- adv_dbg(state, "AFE Default input set to %d\n", afe->input);
-
/* Entity pads and sinks are 0-indexed to match the pads */
for (i = ADV748X_AFE_SINK_AIN0; i <= ADV748X_AFE_SINK_AIN7; i++)
afe->pads[i].flags = MEDIA_PAD_FL_SINK;
diff --git a/drivers/media/i2c/adv748x/adv748x-core.c b/drivers/media/i2c/adv748x/adv748x-core.c
index 1fe7f97c6d52..4e54148147b9 100644
--- a/drivers/media/i2c/adv748x/adv748x-core.c
+++ b/drivers/media/i2c/adv748x/adv748x-core.c
@@ -198,7 +198,7 @@ static int adv748x_initialise_clients(struct adv748x_state *state)
return ret;
}
- return adv748x_set_slave_addresses(state);
+ return 0;
}
/**
@@ -516,6 +516,10 @@ static int adv748x_reset(struct adv748x_state *state)
if (ret)
return ret;
+ adv748x_afe_s_input(&state->afe, state->afe.input);
+
+ adv_dbg(state, "AFE Default input set to %d\n", state->afe.input);
+
/* Reset TXA and TXB */
adv748x_tx_power(&state->txa, 1);
adv748x_tx_power(&state->txa, 0);
@@ -526,10 +530,14 @@ static int adv748x_reset(struct adv748x_state *state)
io_write(state, ADV748X_IO_PD, ADV748X_IO_PD_RX_EN);
/* Conditionally enable TXa and TXb. */
- if (is_tx_enabled(&state->txa))
+ if (is_tx_enabled(&state->txa)) {
regval |= ADV748X_IO_10_CSI4_EN;
- if (is_tx_enabled(&state->txb))
+ adv748x_csi2_set_virtual_channel(&state->txa, 0);
+ }
+ if (is_tx_enabled(&state->txb)) {
regval |= ADV748X_IO_10_CSI1_EN;
+ adv748x_csi2_set_virtual_channel(&state->txb, 0);
+ }
io_write(state, ADV748X_IO_10, regval);
/* Use vid_std and v_freq as freerun resolution for CP */
@@ -558,6 +566,18 @@ static int adv748x_identify_chip(struct adv748x_state *state)
}
/* -----------------------------------------------------------------------------
+ * Suspend / Resume
+ */
+
+static int __maybe_unused adv748x_resume_early(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct adv748x_state *state = i2c_get_clientdata(client);
+
+ return adv748x_reset(state);
+}
+
+/* -----------------------------------------------------------------------------
* i2c driver
*/
@@ -589,14 +609,13 @@ static int adv748x_parse_csi2_lanes(struct adv748x_state *state,
unsigned int port,
struct device_node *ep)
{
- struct v4l2_fwnode_endpoint vep;
+ struct v4l2_fwnode_endpoint vep = { .bus_type = V4L2_MBUS_CSI2_DPHY };
unsigned int num_lanes;
int ret;
if (port != ADV748X_PORT_TXA && port != ADV748X_PORT_TXB)
return 0;
- vep.bus_type = V4L2_MBUS_CSI2_DPHY;
ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &vep);
if (ret)
return ret;
@@ -820,10 +839,15 @@ static const struct of_device_id adv748x_of_table[] = {
};
MODULE_DEVICE_TABLE(of, adv748x_of_table);
+static const struct dev_pm_ops adv748x_pm_ops = {
+ SET_LATE_SYSTEM_SLEEP_PM_OPS(NULL, adv748x_resume_early)
+};
+
static struct i2c_driver adv748x_driver = {
.driver = {
.name = "adv748x",
.of_match_table = adv748x_of_table,
+ .pm = &adv748x_pm_ops,
},
.probe_new = adv748x_probe,
.remove = adv748x_remove,
diff --git a/drivers/media/i2c/adv748x/adv748x-csi2.c b/drivers/media/i2c/adv748x/adv748x-csi2.c
index 99bb63d05eef..fa9278a08fde 100644
--- a/drivers/media/i2c/adv748x/adv748x-csi2.c
+++ b/drivers/media/i2c/adv748x/adv748x-csi2.c
@@ -14,8 +14,7 @@
#include "adv748x.h"
-static int adv748x_csi2_set_virtual_channel(struct adv748x_csi2 *tx,
- unsigned int vc)
+int adv748x_csi2_set_virtual_channel(struct adv748x_csi2 *tx, unsigned int vc)
{
return tx_write(tx, ADV748X_CSI_VC_REF, vc << ADV748X_CSI_VC_REF_SHIFT);
}
@@ -313,9 +312,6 @@ int adv748x_csi2_init(struct adv748x_state *state, struct adv748x_csi2 *tx)
if (!is_tx_enabled(tx))
return 0;
- /* Initialise the virtual channel */
- adv748x_csi2_set_virtual_channel(tx, 0);
-
adv748x_subdev_init(&tx->sd, state, &adv748x_csi2_ops,
MEDIA_ENT_F_VID_IF_BRIDGE,
is_txa(tx) ? "txa" : "txb");
diff --git a/drivers/media/i2c/adv748x/adv748x.h b/drivers/media/i2c/adv748x/adv748x.h
index 1061f425ece5..56256c1e8b0d 100644
--- a/drivers/media/i2c/adv748x/adv748x.h
+++ b/drivers/media/i2c/adv748x/adv748x.h
@@ -435,9 +435,11 @@ int adv748x_tx_power(struct adv748x_csi2 *tx, bool on);
int adv748x_afe_init(struct adv748x_afe *afe);
void adv748x_afe_cleanup(struct adv748x_afe *afe);
+int adv748x_afe_s_input(struct adv748x_afe *afe, unsigned int input);
int adv748x_csi2_init(struct adv748x_state *state, struct adv748x_csi2 *tx);
void adv748x_csi2_cleanup(struct adv748x_csi2 *tx);
+int adv748x_csi2_set_virtual_channel(struct adv748x_csi2 *tx, unsigned int vc);
int adv748x_csi2_set_pixelrate(struct v4l2_subdev *sd, s64 rate);
int adv748x_hdmi_init(struct adv748x_hdmi *hdmi);