33
44#include <linux/acpi.h>
55#include <linux/clk.h>
6+ #include <linux/delay.h>
7+ #include <linux/gpio/consumer.h>
68#include <linux/i2c.h>
79#include <linux/module.h>
10+ #include <linux/of.h>
811#include <linux/pm_runtime.h>
12+ #include <linux/regulator/consumer.h>
913#include <linux/unaligned.h>
1014
1115#include <media/v4l2-ctrls.h>
@@ -125,6 +129,15 @@ struct imx355 {
125129 * Protect access to sensor v4l2 controls.
126130 */
127131 struct mutex mutex ;
132+
133+ struct gpio_desc * reset_gpio ;
134+ struct regulator_bulk_data * supplies ;
135+ };
136+
137+ static const struct regulator_bulk_data imx355_supplies [] = {
138+ { .supply = "avdd" },
139+ { .supply = "dvdd" },
140+ { .supply = "dovdd" },
128141};
129142
130143static const struct imx355_reg imx355_global_regs [] = {
@@ -1515,6 +1528,52 @@ static const struct v4l2_subdev_internal_ops imx355_internal_ops = {
15151528 .open = imx355_open ,
15161529};
15171530
1531+ static int imx355_power_off (struct device * dev )
1532+ {
1533+ struct i2c_client * client = container_of (dev , struct i2c_client , dev );
1534+ struct v4l2_subdev * sd = i2c_get_clientdata (client );
1535+ struct imx355 * imx355 = to_imx355 (sd );
1536+
1537+ gpiod_set_value_cansleep (imx355 -> reset_gpio , 1 );
1538+
1539+ regulator_bulk_disable (ARRAY_SIZE (imx355_supplies ), imx355 -> supplies );
1540+ clk_disable_unprepare (imx355 -> clk );
1541+
1542+ return 0 ;
1543+ }
1544+
1545+ static int imx355_power_on (struct device * dev )
1546+ {
1547+ struct i2c_client * client = container_of (dev , struct i2c_client , dev );
1548+ struct v4l2_subdev * sd = i2c_get_clientdata (client );
1549+ struct imx355 * imx355 = to_imx355 (sd );
1550+ int ret ;
1551+
1552+ ret = clk_prepare_enable (imx355 -> clk );
1553+ if (ret )
1554+ return dev_err_probe (dev , ret , "failed to enable clocks" );
1555+
1556+ ret = regulator_bulk_enable (ARRAY_SIZE (imx355_supplies ),
1557+ imx355 -> supplies );
1558+ if (ret ) {
1559+ dev_err_probe (dev , ret , "failed to enable regulators" );
1560+ goto error_disable_clocks ;
1561+ }
1562+
1563+ usleep_range (1000 , 2000 );
1564+ gpiod_set_value_cansleep (imx355 -> reset_gpio , 0 );
1565+ usleep_range (10000 , 11000 );
1566+
1567+ return 0 ;
1568+
1569+ error_disable_clocks :
1570+ clk_disable_unprepare (imx355 -> clk );
1571+ return ret ;
1572+ }
1573+
1574+ static DEFINE_RUNTIME_DEV_PM_OPS (imx355_pm_ops , imx355_power_off ,
1575+ imx355_power_on , NULL) ;
1576+
15181577/* Initialize control handlers */
15191578static int imx355_init_controls (struct imx355 * imx355 )
15201579{
@@ -1689,30 +1748,51 @@ static int imx355_probe(struct i2c_client *client)
16891748 "external clock %lu is not supported\n" ,
16901749 freq );
16911750
1692- /* Initialize subdev */
1693- v4l2_i2c_subdev_init (& imx355 -> sd , client , & imx355_subdev_ops );
1694-
1695- /* Check module identity */
1696- ret = imx355_identify_module (imx355 );
1751+ ret = devm_regulator_bulk_get_const (imx355 -> dev ,
1752+ ARRAY_SIZE (imx355_supplies ),
1753+ imx355_supplies ,
1754+ & imx355 -> supplies );
16971755 if (ret ) {
1698- dev_err (imx355 -> dev , "failed to find sensor: %d" , ret );
1756+ dev_err_probe (imx355 -> dev , ret , "could not get regulators" );
16991757 goto error_probe ;
17001758 }
17011759
1760+ imx355 -> reset_gpio = devm_gpiod_get_optional (imx355 -> dev , "reset" ,
1761+ GPIOD_OUT_HIGH );
1762+ if (IS_ERR (imx355 -> reset_gpio )) {
1763+ ret = dev_err_probe (imx355 -> dev , PTR_ERR (imx355 -> reset_gpio ),
1764+ "failed to get gpios" );
1765+ goto error_probe ;
1766+ }
1767+
1768+ /* Initialize subdev */
1769+ v4l2_i2c_subdev_init (& imx355 -> sd , client , & imx355_subdev_ops );
1770+
17021771 imx355 -> hwcfg = imx355_get_hwcfg (imx355 -> dev );
17031772 if (!imx355 -> hwcfg ) {
17041773 dev_err (imx355 -> dev , "failed to get hwcfg" );
17051774 ret = - ENODEV ;
17061775 goto error_probe ;
17071776 }
17081777
1778+ ret = imx355_power_on (imx355 -> dev );
1779+ if (ret )
1780+ goto error_probe ;
1781+
1782+ /* Check module identity */
1783+ ret = imx355_identify_module (imx355 );
1784+ if (ret ) {
1785+ dev_err (imx355 -> dev , "failed to find sensor: %d" , ret );
1786+ goto error_power_off ;
1787+ }
1788+
17091789 /* Set default mode to max resolution */
17101790 imx355 -> cur_mode = & supported_modes [0 ];
17111791
17121792 ret = imx355_init_controls (imx355 );
17131793 if (ret ) {
17141794 dev_err (imx355 -> dev , "failed to init controls: %d" , ret );
1715- goto error_probe ;
1795+ goto error_power_off ;
17161796 }
17171797
17181798 /* Initialize subdev */
@@ -1752,6 +1832,9 @@ static int imx355_probe(struct i2c_client *client)
17521832error_handler_free :
17531833 v4l2_ctrl_handler_free (imx355 -> sd .ctrl_handler );
17541834
1835+ error_power_off :
1836+ imx355_power_off (imx355 -> dev );
1837+
17551838error_probe :
17561839 mutex_destroy (& imx355 -> mutex );
17571840
@@ -1768,7 +1851,11 @@ static void imx355_remove(struct i2c_client *client)
17681851 v4l2_ctrl_handler_free (sd -> ctrl_handler );
17691852
17701853 pm_runtime_disable (imx355 -> dev );
1771- pm_runtime_set_suspended (imx355 -> dev );
1854+
1855+ if (!pm_runtime_status_suspended (imx355 -> dev )) {
1856+ imx355_power_off (imx355 -> dev );
1857+ pm_runtime_set_suspended (imx355 -> dev );
1858+ }
17721859
17731860 mutex_destroy (& imx355 -> mutex );
17741861}
@@ -1779,10 +1866,18 @@ static const struct acpi_device_id imx355_acpi_ids[] __maybe_unused = {
17791866};
17801867MODULE_DEVICE_TABLE (acpi , imx355_acpi_ids );
17811868
1869+ static const struct of_device_id imx355_match_table [] = {
1870+ { .compatible = "sony,imx355" , },
1871+ { /* sentinel */ }
1872+ };
1873+ MODULE_DEVICE_TABLE (of , imx355_match_table );
1874+
17821875static struct i2c_driver imx355_i2c_driver = {
17831876 .driver = {
17841877 .name = "imx355" ,
17851878 .acpi_match_table = ACPI_PTR (imx355_acpi_ids ),
1879+ .of_match_table = imx355_match_table ,
1880+ .pm = & imx355_pm_ops ,
17861881 },
17871882 .probe = imx355_probe ,
17881883 .remove = imx355_remove ,
0 commit comments