static int shuttle_camera_resume(struct platform_device *pdev) { struct shuttle_pm_camera_data *camera_data = dev_get_drvdata(&pdev->dev); dev_dbg(&pdev->dev, "resuming\n"); __shuttle_pm_camera_power(&pdev->dev, camera_data->pre_resume_state); return 0; }
static int shuttle_camera_suspend(struct platform_device *pdev, pm_message_t state) { struct shuttle_pm_camera_data *camera_data = dev_get_drvdata(&pdev->dev); dev_dbg(&pdev->dev, "suspending\n"); camera_data->pre_resume_state = camera_data->state; __shuttle_pm_camera_power(&pdev->dev, 0); return 0; }
static ssize_t camera_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long on = simple_strtoul(buf, NULL, 10); /*struct shuttle_pm_camera_data *camera_data = dev_get_drvdata(dev);*/ if (!strcmp(attr->attr.name, "power_on")) { __shuttle_pm_camera_power(dev, on); } return count; }
static int shuttle_camera_suspend(struct platform_device *pdev, pm_message_t state) { struct shuttle_pm_camera_data *camera_data = dev_get_drvdata(&pdev->dev); dev_dbg(&pdev->dev, "suspending\n"); camera_data->pre_resume_state = camera_data->powered_up; if (!camera_data->keep_on_in_suspend) __shuttle_pm_camera_power(&pdev->dev, 0); else dev_warn(&pdev->dev, "keeping camera ON during suspend\n"); return 0; }
static int shuttle_camera_remove(struct platform_device *pdev) { struct shuttle_pm_camera_data *camera_data = dev_get_drvdata(&pdev->dev); if (!camera_data) return 0; sysfs_remove_group(&pdev->dev.kobj, &shuttle_camera_attr_group); __shuttle_pm_camera_power(&pdev->dev, 0); regulator_put(camera_data->regulator); kfree(camera_data); dev_set_drvdata(&pdev->dev, NULL); return 0; }
static ssize_t camera_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long on = simple_strtoul(buf, NULL, 10); struct shuttle_pm_camera_data *camera_data = dev_get_drvdata(dev); if (!strcmp(attr->attr.name, "power_on")) { __shuttle_pm_camera_power(dev, !!on); } #ifdef CONFIG_PM else if (!strcmp(attr->attr.name, "keep_on_in_suspend")) { camera_data->keep_on_in_suspend = on; } #endif return count; }
/* ----- Initialization/removal -------------------------------------------- */ static int __init shuttle_camera_probe(struct platform_device *pdev) { /* default-off */ const int default_state = 0; struct regulator *regulator; struct shuttle_pm_camera_data *camera_data; camera_data = kzalloc(sizeof(*camera_data), GFP_KERNEL); if (!camera_data) { dev_err(&pdev->dev, "no memory for context\n"); return -ENOMEM; } dev_set_drvdata(&pdev->dev, camera_data); regulator = regulator_get(&pdev->dev, "vdd_camera"); if (IS_ERR(regulator)) { dev_err(&pdev->dev, "unable to get regulator 0\n"); kfree(camera_data); dev_set_drvdata(&pdev->dev, NULL); return -ENODEV; } camera_data->regulator = regulator; /* Init io pins and disable camera */ gpio_request(SHUTTLE_CAMERA_POWER, "camera_power"); gpio_direction_output(SHUTTLE_CAMERA_POWER, 0); /* Set the default state */ __shuttle_pm_camera_power(&pdev->dev, default_state); dev_info(&pdev->dev, "Camera power management driver loaded\n"); return sysfs_create_group(&pdev->dev.kobj, &shuttle_camera_attr_group); }