diff options
Diffstat (limited to 'drivers/leds/leds-lm355x.c')
| -rw-r--r-- | drivers/leds/leds-lm355x.c | 147 |
1 files changed, 51 insertions, 96 deletions
diff --git a/drivers/leds/leds-lm355x.c b/drivers/leds/leds-lm355x.c index d81a8e7afd6c..f68771b9eac6 100644 --- a/drivers/leds/leds-lm355x.c +++ b/drivers/leds/leds-lm355x.c @@ -1,22 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Simple driver for Texas Instruments LM355x LED Flash driver chip * Copyright (C) 2012 Texas Instruments -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License version 2 as -* published by the Free Software Foundation. */ #include <linux/module.h> #include <linux/delay.h> #include <linux/i2c.h> -#include <linux/gpio.h> #include <linux/leds.h> #include <linux/slab.h> #include <linux/platform_device.h> #include <linux/fs.h> #include <linux/regmap.h> -#include <linux/workqueue.h> #include <linux/platform_data/leds-lm355x.h> enum lm355x_type { @@ -59,14 +54,6 @@ struct lm355x_chip_data { struct led_classdev cdev_torch; struct led_classdev cdev_indicator; - struct work_struct work_flash; - struct work_struct work_torch; - struct work_struct work_indicator; - - u8 br_flash; - u8 br_torch; - u8 br_indicator; - struct lm355x_platform_data *pdata; struct regmap *regmap; struct mutex lock; @@ -177,18 +164,19 @@ static int lm355x_chip_init(struct lm355x_chip_data *chip) /* input and output pins configuration */ switch (chip->type) { case CHIP_LM3554: - reg_val = pdata->pin_tx2 | pdata->ntc_pin; + reg_val = (u32)pdata->pin_tx2 | (u32)pdata->ntc_pin; ret = regmap_update_bits(chip->regmap, 0xE0, 0x28, reg_val); if (ret < 0) goto out; - reg_val = pdata->pass_mode; + reg_val = (u32)pdata->pass_mode; ret = regmap_update_bits(chip->regmap, 0xA0, 0x04, reg_val); if (ret < 0) goto out; break; case CHIP_LM3556: - reg_val = pdata->pin_tx2 | pdata->ntc_pin | pdata->pass_mode; + reg_val = (u32)pdata->pin_tx2 | (u32)pdata->ntc_pin | + (u32)pdata->pass_mode; ret = regmap_update_bits(chip->regmap, 0x0A, 0xC4, reg_val); if (ret < 0) goto out; @@ -204,7 +192,7 @@ out: } /* chip control */ -static void lm355x_control(struct lm355x_chip_data *chip, +static int lm355x_control(struct lm355x_chip_data *chip, u8 brightness, enum lm355x_mode opmode) { int ret; @@ -301,7 +289,7 @@ static void lm355x_control(struct lm355x_chip_data *chip, case MODE_SHDN: break; default: - return; + return -EINVAL; } /* operation mode control */ ret = regmap_update_bits(chip->regmap, preg[REG_OPMODE].regno, @@ -309,79 +297,61 @@ static void lm355x_control(struct lm355x_chip_data *chip, opmode << preg[REG_OPMODE].shift); if (ret < 0) goto out; - return; + return ret; out: dev_err(chip->dev, "%s:i2c access fail to register\n", __func__); - return; + return ret; } /* torch */ -static void lm355x_deferred_torch_brightness_set(struct work_struct *work) -{ - struct lm355x_chip_data *chip = - container_of(work, struct lm355x_chip_data, work_torch); - - mutex_lock(&chip->lock); - lm355x_control(chip, chip->br_torch, MODE_TORCH); - mutex_unlock(&chip->lock); -} -static void lm355x_torch_brightness_set(struct led_classdev *cdev, +static int lm355x_torch_brightness_set(struct led_classdev *cdev, enum led_brightness brightness) { struct lm355x_chip_data *chip = container_of(cdev, struct lm355x_chip_data, cdev_torch); - - chip->br_torch = brightness; - schedule_work(&chip->work_torch); -} - -/* flash */ -static void lm355x_deferred_strobe_brightness_set(struct work_struct *work) -{ - struct lm355x_chip_data *chip = - container_of(work, struct lm355x_chip_data, work_flash); + int ret; mutex_lock(&chip->lock); - lm355x_control(chip, chip->br_flash, MODE_FLASH); + ret = lm355x_control(chip, brightness, MODE_TORCH); mutex_unlock(&chip->lock); + return ret; } -static void lm355x_strobe_brightness_set(struct led_classdev *cdev, +/* flash */ + +static int lm355x_strobe_brightness_set(struct led_classdev *cdev, enum led_brightness brightness) { struct lm355x_chip_data *chip = container_of(cdev, struct lm355x_chip_data, cdev_flash); - - chip->br_flash = brightness; - schedule_work(&chip->work_flash); -} - -/* indicator */ -static void lm355x_deferred_indicator_brightness_set(struct work_struct *work) -{ - struct lm355x_chip_data *chip = - container_of(work, struct lm355x_chip_data, work_indicator); + int ret; mutex_lock(&chip->lock); - lm355x_control(chip, chip->br_indicator, MODE_INDIC); + ret = lm355x_control(chip, brightness, MODE_FLASH); mutex_unlock(&chip->lock); + return ret; } -static void lm355x_indicator_brightness_set(struct led_classdev *cdev, +/* indicator */ + +static int lm355x_indicator_brightness_set(struct led_classdev *cdev, enum led_brightness brightness) { struct lm355x_chip_data *chip = container_of(cdev, struct lm355x_chip_data, cdev_indicator); + int ret; - chip->br_indicator = brightness; - schedule_work(&chip->work_indicator); + mutex_lock(&chip->lock); + ret = lm355x_control(chip, brightness, MODE_INDIC); + mutex_unlock(&chip->lock); + return ret; } /* indicator pattern only for lm3556*/ -static ssize_t lm3556_indicator_pattern_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t size) +static ssize_t pattern_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) { ssize_t ret; struct led_classdev *led_cdev = dev_get_drvdata(dev); @@ -411,7 +381,13 @@ out: return ret; } -static DEVICE_ATTR(pattern, S_IWUSR, NULL, lm3556_indicator_pattern_store); +static DEVICE_ATTR_WO(pattern); + +static struct attribute *lm355x_indicator_attrs[] = { + &dev_attr_pattern.attr, + NULL +}; +ATTRIBUTE_GROUPS(lm355x_indicator); static const struct regmap_config lm355x_regmap = { .reg_bits = 8, @@ -420,10 +396,10 @@ static const struct regmap_config lm355x_regmap = { }; /* module initialize */ -static int lm355x_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int lm355x_probe(struct i2c_client *client) { - struct lm355x_platform_data *pdata = client->dev.platform_data; + const struct i2c_device_id *id = i2c_client_get_device_id(client); + struct lm355x_platform_data *pdata = dev_get_platdata(&client->dev); struct lm355x_chip_data *chip; int err; @@ -473,53 +449,40 @@ static int lm355x_probe(struct i2c_client *client, goto err_out; /* flash */ - INIT_WORK(&chip->work_flash, lm355x_deferred_strobe_brightness_set); chip->cdev_flash.name = "flash"; chip->cdev_flash.max_brightness = 16; - chip->cdev_flash.brightness_set = lm355x_strobe_brightness_set; + chip->cdev_flash.brightness_set_blocking = lm355x_strobe_brightness_set; chip->cdev_flash.default_trigger = "flash"; - err = led_classdev_register((struct device *) - &client->dev, &chip->cdev_flash); + err = led_classdev_register(&client->dev, &chip->cdev_flash); if (err < 0) goto err_out; /* torch */ - INIT_WORK(&chip->work_torch, lm355x_deferred_torch_brightness_set); chip->cdev_torch.name = "torch"; chip->cdev_torch.max_brightness = 8; - chip->cdev_torch.brightness_set = lm355x_torch_brightness_set; + chip->cdev_torch.brightness_set_blocking = lm355x_torch_brightness_set; chip->cdev_torch.default_trigger = "torch"; - err = led_classdev_register((struct device *) - &client->dev, &chip->cdev_torch); + err = led_classdev_register(&client->dev, &chip->cdev_torch); if (err < 0) goto err_create_torch_file; /* indicator */ - INIT_WORK(&chip->work_indicator, - lm355x_deferred_indicator_brightness_set); chip->cdev_indicator.name = "indicator"; if (id->driver_data == CHIP_LM3554) chip->cdev_indicator.max_brightness = 4; else chip->cdev_indicator.max_brightness = 8; - chip->cdev_indicator.brightness_set = lm355x_indicator_brightness_set; - err = led_classdev_register((struct device *) - &client->dev, &chip->cdev_indicator); + chip->cdev_indicator.brightness_set_blocking = + lm355x_indicator_brightness_set; + /* indicator pattern control only for LM3556 */ + if (id->driver_data == CHIP_LM3556) + chip->cdev_indicator.groups = lm355x_indicator_groups; + err = led_classdev_register(&client->dev, &chip->cdev_indicator); if (err < 0) goto err_create_indicator_file; - /* indicator pattern control only for LM3554 */ - if (id->driver_data == CHIP_LM3556) { - err = - device_create_file(chip->cdev_indicator.dev, - &dev_attr_pattern); - if (err < 0) - goto err_create_pattern_file; - } dev_info(&client->dev, "%s is initialized\n", lm355x_name[id->driver_data]); return 0; -err_create_pattern_file: - led_classdev_unregister(&chip->cdev_indicator); err_create_indicator_file: led_classdev_unregister(&chip->cdev_torch); err_create_torch_file: @@ -528,23 +491,16 @@ err_out: return err; } -static int lm355x_remove(struct i2c_client *client) +static void lm355x_remove(struct i2c_client *client) { struct lm355x_chip_data *chip = i2c_get_clientdata(client); struct lm355x_reg_data *preg = chip->regs; regmap_write(chip->regmap, preg[REG_OPMODE].regno, 0); - if (chip->type == CHIP_LM3556) - device_remove_file(chip->cdev_indicator.dev, &dev_attr_pattern); led_classdev_unregister(&chip->cdev_indicator); - flush_work(&chip->work_indicator); led_classdev_unregister(&chip->cdev_torch); - flush_work(&chip->work_torch); led_classdev_unregister(&chip->cdev_flash); - flush_work(&chip->work_flash); dev_info(&client->dev, "%s is removed\n", lm355x_name[chip->type]); - - return 0; } static const struct i2c_device_id lm355x_id[] = { @@ -558,7 +514,6 @@ MODULE_DEVICE_TABLE(i2c, lm355x_id); static struct i2c_driver lm355x_i2c_driver = { .driver = { .name = LM355x_NAME, - .owner = THIS_MODULE, .pm = NULL, }, .probe = lm355x_probe, |
