From 16ee2323d850d200d43daa761467901ba3c1729c Mon Sep 17 00:00:00 2001 From: Shunqian Zheng Date: Mon, 22 Jul 2019 02:31:04 +0000 Subject: [PATCH] media: spi: add mclk for rk1608 driver RK1608 requires 24M mclk to power on. Some boards(like our rk1608 board) use external clock source, some are not. This patch adds 24M mclk reference in rk1608 driver, and enables it when power on, disables when power off. Change-Id: I97dc5eeb7c921b53aa2b1edc70926b43a6cc18cd Signed-off-by: Shunqian Zheng --- drivers/media/spi/rk1608.c | 22 ++++++++++++++++++++++ drivers/media/spi/rk1608.h | 2 ++ 2 files changed, 24 insertions(+) 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;