forked from mirrors/linux
		
	media: ov7670: Add the ov7670_s_power function
Add the ov7670_s_power function which is responsible for manipulating the power dowm mode through the PWDN pin and the reset operation through the RESET pin, and keep it powered at all times. [sakari.ailus@linux.intel.com: set pwdn_gpio direction only once] Signed-off-by: Wenyou Yang <wenyou.yang@microchip.com> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
This commit is contained in:
		
							parent
							
								
									c0662dd4e7
								
							
						
					
					
						commit
						71862f63f3
					
				
					 1 changed files with 26 additions and 5 deletions
				
			
		| 
						 | 
					@ -1544,6 +1544,22 @@ static int ov7670_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_regis
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int ov7670_s_power(struct v4l2_subdev *sd, int on)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ov7670_info *info = to_state(sd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (info->pwdn_gpio)
 | 
				
			||||||
 | 
							gpiod_set_value(info->pwdn_gpio, !on);
 | 
				
			||||||
 | 
						if (on && info->resetb_gpio) {
 | 
				
			||||||
 | 
							gpiod_set_value(info->resetb_gpio, 1);
 | 
				
			||||||
 | 
							usleep_range(500, 1000);
 | 
				
			||||||
 | 
							gpiod_set_value(info->resetb_gpio, 0);
 | 
				
			||||||
 | 
							usleep_range(3000, 5000);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void ov7670_get_default_format(struct v4l2_subdev *sd,
 | 
					static void ov7670_get_default_format(struct v4l2_subdev *sd,
 | 
				
			||||||
				      struct v4l2_mbus_framefmt *format)
 | 
									      struct v4l2_mbus_framefmt *format)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -1694,23 +1710,25 @@ static int ov7670_probe(struct i2c_client *client,
 | 
				
			||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = ov7670_init_gpio(client, info);
 | 
					 | 
				
			||||||
	if (ret)
 | 
					 | 
				
			||||||
		goto clk_disable;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	info->clock_speed = clk_get_rate(info->clk) / 1000000;
 | 
						info->clock_speed = clk_get_rate(info->clk) / 1000000;
 | 
				
			||||||
	if (info->clock_speed < 10 || info->clock_speed > 48) {
 | 
						if (info->clock_speed < 10 || info->clock_speed > 48) {
 | 
				
			||||||
		ret = -EINVAL;
 | 
							ret = -EINVAL;
 | 
				
			||||||
		goto clk_disable;
 | 
							goto clk_disable;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = ov7670_init_gpio(client, info);
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
 | 
							goto clk_disable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ov7670_s_power(sd, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Make sure it's an ov7670 */
 | 
						/* Make sure it's an ov7670 */
 | 
				
			||||||
	ret = ov7670_detect(sd);
 | 
						ret = ov7670_detect(sd);
 | 
				
			||||||
	if (ret) {
 | 
						if (ret) {
 | 
				
			||||||
		v4l_dbg(1, debug, client,
 | 
							v4l_dbg(1, debug, client,
 | 
				
			||||||
			"chip found @ 0x%x (%s) is not an ov7670 chip.\n",
 | 
								"chip found @ 0x%x (%s) is not an ov7670 chip.\n",
 | 
				
			||||||
			client->addr << 1, client->adapter->name);
 | 
								client->addr << 1, client->adapter->name);
 | 
				
			||||||
		goto clk_disable;
 | 
							goto power_off;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	v4l_info(client, "chip found @ 0x%02x (%s)\n",
 | 
						v4l_info(client, "chip found @ 0x%02x (%s)\n",
 | 
				
			||||||
			client->addr << 1, client->adapter->name);
 | 
								client->addr << 1, client->adapter->name);
 | 
				
			||||||
| 
						 | 
					@ -1789,6 +1807,8 @@ static int ov7670_probe(struct i2c_client *client,
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
hdl_free:
 | 
					hdl_free:
 | 
				
			||||||
	v4l2_ctrl_handler_free(&info->hdl);
 | 
						v4l2_ctrl_handler_free(&info->hdl);
 | 
				
			||||||
 | 
					power_off:
 | 
				
			||||||
 | 
						ov7670_s_power(sd, 0);
 | 
				
			||||||
clk_disable:
 | 
					clk_disable:
 | 
				
			||||||
	clk_disable_unprepare(info->clk);
 | 
						clk_disable_unprepare(info->clk);
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
| 
						 | 
					@ -1806,6 +1826,7 @@ static int ov7670_remove(struct i2c_client *client)
 | 
				
			||||||
#if defined(CONFIG_MEDIA_CONTROLLER)
 | 
					#if defined(CONFIG_MEDIA_CONTROLLER)
 | 
				
			||||||
	media_entity_cleanup(&info->sd.entity);
 | 
						media_entity_cleanup(&info->sd.entity);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
						ov7670_s_power(sd, 0);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue