static int max77693_led_flash_strobe_set( struct led_classdev_flash *fled_cdev, bool state) { struct max77693_sub_led *sub_led = flcdev_to_sub_led(fled_cdev); struct max77693_led_device *led = sub_led_to_led(sub_led); int fled_id = sub_led->fled_id; int ret; mutex_lock(&led->lock); if (!state) { ret = max77693_clear_mode(led, MODE_FLASH(fled_id)); goto unlock; } if (sub_led->flash_timeout != led->current_flash_timeout) { ret = max77693_set_timeout(led, sub_led->flash_timeout); if (ret < 0) goto unlock; } led->strobing_sub_led_id = fled_id; ret = max77693_add_mode(led, MODE_FLASH(fled_id)); if (ret < 0) goto unlock; ret = max77693_get_flash_faults(sub_led); unlock: mutex_unlock(&led->lock); return ret; }
static int max77693_led_brightness_set_sync( struct led_classdev *led_cdev, enum led_brightness value) { struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(led_cdev); struct max77693_sub_led *sub_led = flcdev_to_sub_led(fled_cdev); struct max77693_led_device *led = sub_led_to_led(sub_led); return __max77693_led_brightness_set(led, sub_led->fled_id, value); }
static void max77693_led_brightness_set_work( struct work_struct *work) { struct max77693_sub_led *sub_led = container_of(work, struct max77693_sub_led, work_brightness_set); struct max77693_led_device *led = sub_led_to_led(sub_led); __max77693_led_brightness_set(led, sub_led->fled_id, sub_led->torch_brightness); }
static int max77693_led_flash_timeout_set( struct led_classdev_flash *fled_cdev, u32 timeout) { struct max77693_sub_led *sub_led = flcdev_to_sub_led(fled_cdev); struct max77693_led_device *led = sub_led_to_led(sub_led); mutex_lock(&led->lock); sub_led->flash_timeout = timeout; mutex_unlock(&led->lock); return 0; }
static int max77693_led_flash_brightness_set( struct led_classdev_flash *fled_cdev, u32 brightness) { struct max77693_sub_led *sub_led = flcdev_to_sub_led(fled_cdev); struct max77693_led_device *led = sub_led_to_led(sub_led); int ret; mutex_lock(&led->lock); ret = max77693_set_flash_current(led, sub_led->fled_id, brightness); mutex_unlock(&led->lock); return ret; }
static int max77693_led_flash_strobe_get( struct led_classdev_flash *fled_cdev, bool *state) { struct max77693_sub_led *sub_led = flcdev_to_sub_led(fled_cdev); struct max77693_led_device *led = sub_led_to_led(sub_led); int ret; if (!state) return -EINVAL; mutex_lock(&led->lock); ret = max77693_get_strobe_status(led, state); *state = !!(*state && (led->strobing_sub_led_id == sub_led->fled_id)); mutex_unlock(&led->lock); return ret; }
/* LED subsystem callbacks */ static int max77693_led_brightness_set(struct led_classdev *led_cdev, enum led_brightness value) { struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(led_cdev); struct max77693_sub_led *sub_led = flcdev_to_sub_led(fled_cdev); struct max77693_led_device *led = sub_led_to_led(sub_led); int fled_id = sub_led->fled_id, ret; mutex_lock(&led->lock); if (value == 0) { ret = max77693_clear_mode(led, MODE_TORCH(fled_id)); if (ret < 0) dev_dbg(&led->pdev->dev, "Failed to clear torch mode (%d)\n", ret); goto unlock; } ret = max77693_set_torch_current(led, fled_id, value * TORCH_IOUT_STEP); if (ret < 0) { dev_dbg(&led->pdev->dev, "Failed to set torch current (%d)\n", ret); goto unlock; } ret = max77693_add_mode(led, MODE_TORCH(fled_id)); if (ret < 0) dev_dbg(&led->pdev->dev, "Failed to set torch mode (%d)\n", ret); unlock: mutex_unlock(&led->lock); return ret; }
static int max77693_get_flash_faults(struct max77693_sub_led *sub_led) { struct max77693_led_device *led = sub_led_to_led(sub_led); struct regmap *rmap = led->regmap; unsigned int v; u8 fault_open_mask, fault_short_mask; int ret; sub_led->flash_faults = 0; if (led->iout_joint) { fault_open_mask = FLASH_INT_FLED1_OPEN | FLASH_INT_FLED2_OPEN; fault_short_mask = FLASH_INT_FLED1_SHORT | FLASH_INT_FLED2_SHORT; } else { fault_open_mask = (sub_led->fled_id == FLED1) ? FLASH_INT_FLED1_OPEN : FLASH_INT_FLED2_OPEN; fault_short_mask = (sub_led->fled_id == FLED1) ? FLASH_INT_FLED1_SHORT : FLASH_INT_FLED2_SHORT; } ret = regmap_read(rmap, MAX77693_LED_REG_FLASH_INT, &v); if (ret < 0) return ret; if (v & fault_open_mask) sub_led->flash_faults |= LED_FAULT_OVER_VOLTAGE; if (v & fault_short_mask) sub_led->flash_faults |= LED_FAULT_SHORT_CIRCUIT; if (v & FLASH_INT_OVER_CURRENT) sub_led->flash_faults |= LED_FAULT_OVER_CURRENT; return 0; }