33
44#include <asm/unaligned.h>
55#include <linux/acpi.h>
6+ #include <linux/clk.h>
67#include <linux/delay.h>
78#include <linux/i2c.h>
89#include <linux/module.h>
@@ -418,6 +419,8 @@ static const struct og01a1b_mode supported_modes[] = {
418419};
419420
420421struct og01a1b {
422+ struct clk * xvclk ;
423+
421424 struct v4l2_subdev sd ;
422425 struct media_pad pad ;
423426 struct v4l2_ctrl_handler ctrl_handler ;
@@ -898,8 +901,10 @@ static int og01a1b_identify_module(struct og01a1b *og01a1b)
898901 return 0 ;
899902}
900903
901- static int og01a1b_check_hwcfg (struct device * dev )
904+ static int og01a1b_check_hwcfg (struct og01a1b * og01a1b )
902905{
906+ struct i2c_client * client = v4l2_get_subdevdata (& og01a1b -> sd );
907+ struct device * dev = & client -> dev ;
903908 struct fwnode_handle * ep ;
904909 struct fwnode_handle * fwnode = dev_fwnode (dev );
905910 struct v4l2_fwnode_endpoint bus_cfg = {
@@ -913,10 +918,13 @@ static int og01a1b_check_hwcfg(struct device *dev)
913918 return - ENXIO ;
914919
915920 ret = fwnode_property_read_u32 (fwnode , "clock-frequency" , & mclk );
916-
917921 if (ret ) {
918- dev_err (dev , "can't get clock frequency" );
919- return ret ;
922+ if (!og01a1b -> xvclk ) {
923+ dev_err (dev , "can't get clock frequency" );
924+ return ret ;
925+ }
926+
927+ mclk = clk_get_rate (og01a1b -> xvclk );
920928 }
921929
922930 if (mclk != OG01A1B_MCLK ) {
@@ -970,13 +978,32 @@ static int og01a1b_check_hwcfg(struct device *dev)
970978/* Power/clock management functions */
971979static int og01a1b_power_on (struct device * dev )
972980{
973- /* Device is already turned on by i2c-core with ACPI domain PM. */
981+ unsigned long delay = DIV_ROUND_UP (8192UL * USEC_PER_SEC , OG01A1B_MCLK );
982+ struct v4l2_subdev * sd = dev_get_drvdata (dev );
983+ struct og01a1b * og01a1b = to_og01a1b (sd );
984+ int ret ;
985+
986+ ret = clk_prepare_enable (og01a1b -> xvclk );
987+ if (ret )
988+ return ret ;
989+
990+ if (og01a1b -> xvclk )
991+ usleep_range (delay , 2 * delay );
974992
975993 return 0 ;
976994}
977995
978996static int og01a1b_power_off (struct device * dev )
979997{
998+ unsigned long delay = DIV_ROUND_UP (512 * USEC_PER_SEC , OG01A1B_MCLK );
999+ struct v4l2_subdev * sd = dev_get_drvdata (dev );
1000+ struct og01a1b * og01a1b = to_og01a1b (sd );
1001+
1002+ if (og01a1b -> xvclk )
1003+ usleep_range (delay , 2 * delay );
1004+
1005+ clk_disable_unprepare (og01a1b -> xvclk );
1006+
9801007 return 0 ;
9811008}
9821009
@@ -1003,7 +1030,14 @@ static int og01a1b_probe(struct i2c_client *client)
10031030
10041031 v4l2_i2c_subdev_init (& og01a1b -> sd , client , & og01a1b_subdev_ops );
10051032
1006- ret = og01a1b_check_hwcfg (& client -> dev );
1033+ og01a1b -> xvclk = devm_clk_get_optional (& client -> dev , NULL );
1034+ if (IS_ERR (og01a1b -> xvclk )) {
1035+ ret = PTR_ERR (og01a1b -> xvclk );
1036+ dev_err (& client -> dev , "failed to get xvclk clock: %d\n" , ret );
1037+ return ret ;
1038+ }
1039+
1040+ ret = og01a1b_check_hwcfg (og01a1b );
10071041 if (ret ) {
10081042 dev_err (& client -> dev , "failed to check HW configuration: %d" ,
10091043 ret );
0 commit comments