99#include <linux/i2c.h>
1010#include <linux/module.h>
1111#include <linux/pm_runtime.h>
12+ #include <linux/regulator/consumer.h>
1213#include <media/v4l2-ctrls.h>
1314#include <media/v4l2-device.h>
1415#include <media/v4l2-fwnode.h>
@@ -422,6 +423,9 @@ static const struct og01a1b_mode supported_modes[] = {
422423struct og01a1b {
423424 struct clk * xvclk ;
424425 struct gpio_desc * reset_gpio ;
426+ struct regulator * avdd ;
427+ struct regulator * dovdd ;
428+ struct regulator * dvdd ;
425429
426430 struct v4l2_subdev sd ;
427431 struct media_pad pad ;
@@ -985,9 +989,27 @@ static int og01a1b_power_on(struct device *dev)
985989 struct og01a1b * og01a1b = to_og01a1b (sd );
986990 int ret ;
987991
992+ if (og01a1b -> avdd ) {
993+ ret = regulator_enable (og01a1b -> avdd );
994+ if (ret )
995+ return ret ;
996+ }
997+
998+ if (og01a1b -> dovdd ) {
999+ ret = regulator_enable (og01a1b -> dovdd );
1000+ if (ret )
1001+ goto avdd_disable ;
1002+ }
1003+
1004+ if (og01a1b -> dvdd ) {
1005+ ret = regulator_enable (og01a1b -> dvdd );
1006+ if (ret )
1007+ goto dovdd_disable ;
1008+ }
1009+
9881010 ret = clk_prepare_enable (og01a1b -> xvclk );
9891011 if (ret )
990- return ret ;
1012+ goto dvdd_disable ;
9911013
9921014 gpiod_set_value_cansleep (og01a1b -> reset_gpio , 0 );
9931015
@@ -997,6 +1019,18 @@ static int og01a1b_power_on(struct device *dev)
9971019 usleep_range (delay , 2 * delay );
9981020
9991021 return 0 ;
1022+
1023+ dvdd_disable :
1024+ if (og01a1b -> dvdd )
1025+ regulator_disable (og01a1b -> dvdd );
1026+ dovdd_disable :
1027+ if (og01a1b -> dovdd )
1028+ regulator_disable (og01a1b -> dovdd );
1029+ avdd_disable :
1030+ if (og01a1b -> avdd )
1031+ regulator_disable (og01a1b -> avdd );
1032+
1033+ return ret ;
10001034}
10011035
10021036static int og01a1b_power_off (struct device * dev )
@@ -1012,6 +1046,15 @@ static int og01a1b_power_off(struct device *dev)
10121046
10131047 gpiod_set_value_cansleep (og01a1b -> reset_gpio , 1 );
10141048
1049+ if (og01a1b -> dvdd )
1050+ regulator_disable (og01a1b -> dvdd );
1051+
1052+ if (og01a1b -> dovdd )
1053+ regulator_disable (og01a1b -> dovdd );
1054+
1055+ if (og01a1b -> avdd )
1056+ regulator_disable (og01a1b -> avdd );
1057+
10151058 return 0 ;
10161059}
10171060
@@ -1059,6 +1102,42 @@ static int og01a1b_probe(struct i2c_client *client)
10591102 return PTR_ERR (og01a1b -> reset_gpio );
10601103 }
10611104
1105+ og01a1b -> avdd = devm_regulator_get_optional (& client -> dev , "avdd" );
1106+ if (IS_ERR (og01a1b -> avdd )) {
1107+ ret = PTR_ERR (og01a1b -> avdd );
1108+ if (ret != - ENODEV ) {
1109+ dev_err_probe (& client -> dev , ret ,
1110+ "Failed to get 'avdd' regulator\n" );
1111+ return ret ;
1112+ }
1113+
1114+ og01a1b -> avdd = NULL ;
1115+ }
1116+
1117+ og01a1b -> dovdd = devm_regulator_get_optional (& client -> dev , "dovdd" );
1118+ if (IS_ERR (og01a1b -> dovdd )) {
1119+ ret = PTR_ERR (og01a1b -> dovdd );
1120+ if (ret != - ENODEV ) {
1121+ dev_err_probe (& client -> dev , ret ,
1122+ "Failed to get 'dovdd' regulator\n" );
1123+ return ret ;
1124+ }
1125+
1126+ og01a1b -> dovdd = NULL ;
1127+ }
1128+
1129+ og01a1b -> dvdd = devm_regulator_get_optional (& client -> dev , "dvdd" );
1130+ if (IS_ERR (og01a1b -> dvdd )) {
1131+ ret = PTR_ERR (og01a1b -> dvdd );
1132+ if (ret != - ENODEV ) {
1133+ dev_err_probe (& client -> dev , ret ,
1134+ "Failed to get 'dvdd' regulator\n" );
1135+ return ret ;
1136+ }
1137+
1138+ og01a1b -> dvdd = NULL ;
1139+ }
1140+
10621141 /* The sensor must be powered on to read the CHIP_ID register */
10631142 ret = og01a1b_power_on (& client -> dev );
10641143 if (ret )
0 commit comments