diff options
author | Terence Ho <terenceh@codeaurora.org> | 2016-09-01 19:42:16 -0400 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-05-26 01:40:05 -0700 |
commit | c16c42a403d279af72feeff11d12095c124933c4 (patch) | |
tree | 811a4d76fcf35420c92c57946d3d263b1d978d61 /drivers/media/i2c | |
parent | 402e3c1d4ed73eefa0b2c674719db481908a5a85 (diff) |
adv7481: Add suspend and resume handler functions
Add suspend and resume handler to be called from power management
framework for driver to release clock votes prior to device goes
into sleep state. Driver requests for the necessary resources in
resume handler
CRs-Fixed: 1062576
Change-Id: Iff9e7ed7b7918f9a371453a020086f22e844d7e4
Signed-off-by: Terence Ho <terenceh@codeaurora.org>
Diffstat (limited to 'drivers/media/i2c')
-rw-r--r-- | drivers/media/i2c/adv7481.c | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/drivers/media/i2c/adv7481.c b/drivers/media/i2c/adv7481.c index 1d839cd8d973..488417df548c 100644 --- a/drivers/media/i2c/adv7481.c +++ b/drivers/media/i2c/adv7481.c @@ -116,6 +116,7 @@ struct adv7481_state { int device_num; int powerup; int cec_detected; + int clocks_requested; /* GPIOs */ struct gpio gpio_array[ADV7481_GPIO_MAX]; @@ -423,6 +424,59 @@ static irqreturn_t adv7481_irq(int irq, void *dev) return IRQ_HANDLED; } +/* Request CCI clocks for adv7481 register access */ +static int adv7481_request_cci_clks(struct adv7481_state *state) +{ + int ret = 0; + + if (state->clocks_requested == TRUE) + return ret; + + ret = state->i2c_client.i2c_func_tbl->i2c_util( + &state->i2c_client, MSM_CCI_INIT); + if (ret < 0) + pr_err("%s - cci_init failed\n", __func__); + else + state->clocks_requested = TRUE; + + /* enable camera voltage regulator */ + ret = msm_camera_enable_vreg(state->dev, state->cci_vreg, + state->regulator_count, NULL, 0, + &state->cci_reg_ptr[0], 1); + if (ret < 0) + pr_err("%s:cci enable_vreg failed\n", __func__); + else + pr_debug("%s - VREG Initialized...\n", __func__); + + return ret; +} + +static int adv7481_release_cci_clks(struct adv7481_state *state) +{ + int ret = 0; + + if (state->clocks_requested == FALSE) + return ret; + + ret = state->i2c_client.i2c_func_tbl->i2c_util( + &state->i2c_client, MSM_CCI_RELEASE); + if (ret < 0) + pr_err("%s - cci_release failed\n", __func__); + else + state->clocks_requested = FALSE; + + /* disable camera voltage regulator */ + ret = msm_camera_enable_vreg(state->dev, state->cci_vreg, + state->regulator_count, NULL, 0, + &state->cci_reg_ptr[0], 0); + if (ret < 0) + pr_err("%s:cci disable vreg failed\n", __func__); + else + pr_debug("%s - VREG Initialized...\n", __func__); + + return ret; +} + static void adv7481_irq_delay_work(struct work_struct *work) { struct adv7481_state *state; @@ -2144,6 +2198,8 @@ static int adv7481_cci_init(struct adv7481_state *state) &state->i2c_client, MSM_CCI_INIT); if (ret < 0) pr_err("%s - cci_init failed\n", __func__); + else + state->clocks_requested = TRUE; pr_debug("%s i2c_client.client: %p\n", __func__, state->i2c_client.client); @@ -2360,11 +2416,54 @@ static int adv7481_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM_SLEEP +static int adv7481_suspend(struct device *dev) +{ + struct adv7481_state *state; + int ret; + + state = (struct adv7481_state *)dev_get_drvdata(dev); + + /* release CCI clocks */ + ret = adv7481_release_cci_clks(state); + if (ret) + pr_err("%s: adv7481 release cci clocks failed\n", __func__); + else + pr_debug("released cci clocks in suspend"); + + return 0; +} + +static int adv7481_resume(struct device *dev) +{ + struct adv7481_state *state; + int ret; + + state = (struct adv7481_state *)dev_get_drvdata(dev); + + /* Request CCI clocks */ + ret = adv7481_request_cci_clks(state); + if (ret) + pr_err("%s: adv7481 request cci clocks failed\n", __func__); + else + pr_debug("requested cci clocks in resume"); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(adv7481_pm_ops, adv7481_suspend, adv7481_resume); +#define ADV7481_PM_OPS (&adv7481_pm_ops) + +#else +#define ADV7481_PM_OPS NULL +#endif + static struct platform_driver adv7481_driver = { .driver = { .owner = THIS_MODULE, .name = KBUILD_MODNAME, .of_match_table = adv7481_id, + .pm = ADV7481_PM_OPS, }, .probe = adv7481_probe, .remove = adv7481_remove, |