diff --git a/drivers/media/spi/rk1608.c b/drivers/media/spi/rk1608.c index d9097ae0d56b..b08480b1c215 100644 --- a/drivers/media/spi/rk1608.c +++ b/drivers/media/spi/rk1608.c @@ -813,6 +813,21 @@ static int rk1608_power_on(struct rk1608_state *pdata) struct spi_device *spi = pdata->spi; int ret = 0; + if (!IS_ERR(pdata->mclk)) { + ret = clk_set_rate(pdata->mclk, RK1608_MCLK_RATE); + if (ret < 0) + dev_warn(pdata->dev, "Failed to set mclk rate\n"); + if (clk_get_rate(pdata->mclk) != RK1608_MCLK_RATE) + dev_warn(pdata->dev, "mclk(%lu) mismatched\n", + clk_get_rate(pdata->mclk)); + + ret = clk_prepare_enable(pdata->mclk); + if (ret < 0) + dev_warn(pdata->dev, "Failed to enable mclk\n"); + else + usleep_range(3000, 3500); + } + /* Request rk1608 enter slave mode */ rk1608_cs_set_value(pdata, 0); if (pdata->wakeup_gpio) @@ -862,6 +877,9 @@ static int rk1608_power_off(struct rk1608_state *pdata) gpiod_direction_output(pdata->reset_gpio, 0); rk1608_cs_set_value(pdata, 0); + if (!IS_ERR(pdata->mclk)) + clk_disable_unprepare(pdata->mclk); + return 0; } @@ -1556,6 +1574,10 @@ static int rk1608_parse_dt_property(struct rk1608_state *pdata) return PTR_ERR(pdata->aesync_gpio); } + pdata->mclk = devm_clk_get(dev, "mclk"); + if (IS_ERR(pdata->mclk)) + dev_warn(dev, "Failed to get mclk, do you use ext 24M clk?\n"); + pdata->msg_num = 0; init_waitqueue_head(&pdata->msg_wait); for (i = 0; i < 8; i++) diff --git a/drivers/media/spi/rk1608.h b/drivers/media/spi/rk1608.h index 7cec0ed2efdd..655b05c5784f 100644 --- a/drivers/media/spi/rk1608.h +++ b/drivers/media/spi/rk1608.h @@ -9,6 +9,7 @@ #ifndef __RK1608_H__ #define __RK1608_H__ +#include #include #include #include @@ -105,6 +106,7 @@ struct rk1608_state { struct v4l2_subdev *sensor[4]; struct device *dev; struct spi_device *spi; + struct clk *mclk; struct miscdevice misc; struct rk1608_client_list clients; int log_level;