Commit 438df3eb authored by Sylwester Nawrocki's avatar Sylwester Nawrocki Committed by Mauro Carvalho Chehab

[media] s5p-csis: Handle all available power supplies

On the SoCs this driver is intended to support the are three separate
pins to supply the MIPI-CSIS subsystem: 1.1V or 1.2V, 1.8V and power
supply for an internal PLL.
This patch adds support for two separate voltage supplies to cover
properly board configurations where PMIC requires to configure
independently each external supply of the MIPI-CSI device. The 1.8V
and PLL supply are assigned a single "vdd18" regulator supply name
as it seems more reasonable than creating separate regulator supplies
for them.

While at here stop using the 'fixed_phy_vdd' platform_data field.
It has been introduced for boards where the MIPI-CSIS supplies are
not controllable. However it is not needed as those boards can use
the dummy regulator.
Signed-off-by: default avatarSylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: default avatarKyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent e9e21083
...@@ -81,6 +81,12 @@ static char *csi_clock_name[] = { ...@@ -81,6 +81,12 @@ static char *csi_clock_name[] = {
}; };
#define NUM_CSIS_CLOCKS ARRAY_SIZE(csi_clock_name) #define NUM_CSIS_CLOCKS ARRAY_SIZE(csi_clock_name)
static const char * const csis_supply_name[] = {
"vdd11", /* 1.1V or 1.2V (s5pc100) MIPI CSI suppply */
"vdd18", /* VDD 1.8V and MIPI CSI PLL supply */
};
#define CSIS_NUM_SUPPLIES ARRAY_SIZE(csis_supply_name)
enum { enum {
ST_POWERED = 1, ST_POWERED = 1,
ST_STREAMING = 2, ST_STREAMING = 2,
...@@ -109,9 +115,9 @@ struct csis_state { ...@@ -109,9 +115,9 @@ struct csis_state {
struct platform_device *pdev; struct platform_device *pdev;
struct resource *regs_res; struct resource *regs_res;
void __iomem *regs; void __iomem *regs;
struct regulator_bulk_data supplies[CSIS_NUM_SUPPLIES];
struct clk *clock[NUM_CSIS_CLOCKS]; struct clk *clock[NUM_CSIS_CLOCKS];
int irq; int irq;
struct regulator *supply;
u32 flags; u32 flags;
const struct csis_pix_format *csis_fmt; const struct csis_pix_format *csis_fmt;
struct v4l2_mbus_framefmt format; struct v4l2_mbus_framefmt format;
...@@ -460,6 +466,7 @@ static int __devinit s5pcsis_probe(struct platform_device *pdev) ...@@ -460,6 +466,7 @@ static int __devinit s5pcsis_probe(struct platform_device *pdev)
struct resource *regs_res; struct resource *regs_res;
struct csis_state *state; struct csis_state *state;
int ret = -ENOMEM; int ret = -ENOMEM;
int i;
state = kzalloc(sizeof(*state), GFP_KERNEL); state = kzalloc(sizeof(*state), GFP_KERNEL);
if (!state) if (!state)
...@@ -519,14 +526,13 @@ static int __devinit s5pcsis_probe(struct platform_device *pdev) ...@@ -519,14 +526,13 @@ static int __devinit s5pcsis_probe(struct platform_device *pdev)
goto e_clkput; goto e_clkput;
} }
if (!pdata->fixed_phy_vdd) { for (i = 0; i < CSIS_NUM_SUPPLIES; i++)
state->supply = regulator_get(&pdev->dev, "vdd"); state->supplies[i].supply = csis_supply_name[i];
if (IS_ERR(state->supply)) {
ret = PTR_ERR(state->supply); ret = regulator_bulk_get(&pdev->dev, CSIS_NUM_SUPPLIES,
state->supply = NULL; state->supplies);
if (ret)
goto e_clkput; goto e_clkput;
}
}
ret = request_irq(state->irq, s5pcsis_irq_handler, 0, ret = request_irq(state->irq, s5pcsis_irq_handler, 0,
dev_name(&pdev->dev), state); dev_name(&pdev->dev), state);
...@@ -561,8 +567,7 @@ static int __devinit s5pcsis_probe(struct platform_device *pdev) ...@@ -561,8 +567,7 @@ static int __devinit s5pcsis_probe(struct platform_device *pdev)
e_irqfree: e_irqfree:
free_irq(state->irq, state); free_irq(state->irq, state);
e_regput: e_regput:
if (state->supply) regulator_bulk_free(CSIS_NUM_SUPPLIES, state->supplies);
regulator_put(state->supply);
e_clkput: e_clkput:
clk_disable(state->clock[CSIS_CLK_MUX]); clk_disable(state->clock[CSIS_CLK_MUX]);
s5pcsis_clk_put(state); s5pcsis_clk_put(state);
...@@ -592,11 +597,10 @@ static int s5pcsis_suspend(struct device *dev) ...@@ -592,11 +597,10 @@ static int s5pcsis_suspend(struct device *dev)
ret = pdata->phy_enable(state->pdev, false); ret = pdata->phy_enable(state->pdev, false);
if (ret) if (ret)
goto unlock; goto unlock;
if (state->supply) { ret = regulator_bulk_disable(CSIS_NUM_SUPPLIES,
ret = regulator_disable(state->supply); state->supplies);
if (ret) if (ret)
goto unlock; goto unlock;
}
clk_disable(state->clock[CSIS_CLK_GATE]); clk_disable(state->clock[CSIS_CLK_GATE]);
state->flags &= ~ST_POWERED; state->flags &= ~ST_POWERED;
} }
...@@ -622,16 +626,16 @@ static int s5pcsis_resume(struct device *dev) ...@@ -622,16 +626,16 @@ static int s5pcsis_resume(struct device *dev)
goto unlock; goto unlock;
if (!(state->flags & ST_POWERED)) { if (!(state->flags & ST_POWERED)) {
if (state->supply) ret = regulator_bulk_enable(CSIS_NUM_SUPPLIES,
ret = regulator_enable(state->supply); state->supplies);
if (ret) if (ret)
goto unlock; goto unlock;
ret = pdata->phy_enable(state->pdev, true); ret = pdata->phy_enable(state->pdev, true);
if (!ret) { if (!ret) {
state->flags |= ST_POWERED; state->flags |= ST_POWERED;
} else if (state->supply) { } else {
regulator_disable(state->supply); regulator_bulk_disable(CSIS_NUM_SUPPLIES,
state->supplies);
goto unlock; goto unlock;
} }
clk_enable(state->clock[CSIS_CLK_GATE]); clk_enable(state->clock[CSIS_CLK_GATE]);
...@@ -679,8 +683,7 @@ static int __devexit s5pcsis_remove(struct platform_device *pdev) ...@@ -679,8 +683,7 @@ static int __devexit s5pcsis_remove(struct platform_device *pdev)
pm_runtime_set_suspended(&pdev->dev); pm_runtime_set_suspended(&pdev->dev);
s5pcsis_clk_put(state); s5pcsis_clk_put(state);
if (state->supply) regulator_bulk_free(CSIS_NUM_SUPPLIES, state->supplies);
regulator_put(state->supply);
media_entity_cleanup(&state->sd.entity); media_entity_cleanup(&state->sd.entity);
free_irq(state->irq, state); free_irq(state->irq, state);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment