Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/drivers/leds/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 7 kB image not shown  

Quelle  leds-max8997.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-only
/*
 * leds-max8997.c - LED class driver for MAX8997 LEDs.
 *
 * Copyright (C) 2011 Samsung Electronics
 * Donggeun Kim <dg77.kim@samsung.com>
 */


#include <linux/module.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/leds.h>
#include <linux/mfd/max8997.h>
#include <linux/mfd/max8997-private.h>
#include <linux/platform_device.h>

#define MAX8997_LED_FLASH_SHIFT   3
#define MAX8997_LED_FLASH_CUR_MASK  0xf8
#define MAX8997_LED_MOVIE_SHIFT   4
#define MAX8997_LED_MOVIE_CUR_MASK  0xf0

#define MAX8997_LED_FLASH_MAX_BRIGHTNESS 0x1f
#define MAX8997_LED_MOVIE_MAX_BRIGHTNESS 0xf
#define MAX8997_LED_NONE_MAX_BRIGHTNESS  0

#define MAX8997_LED0_FLASH_MASK   0x1
#define MAX8997_LED0_FLASH_PIN_MASK  0x5
#define MAX8997_LED0_MOVIE_MASK   0x8
#define MAX8997_LED0_MOVIE_PIN_MASK  0x28

#define MAX8997_LED1_FLASH_MASK   0x2
#define MAX8997_LED1_FLASH_PIN_MASK  0x6
#define MAX8997_LED1_MOVIE_MASK   0x10
#define MAX8997_LED1_MOVIE_PIN_MASK  0x30

#define MAX8997_LED_BOOST_ENABLE_MASK  (1 << 6)

struct max8997_led {
 struct max8997_dev *iodev;
 struct led_classdev cdev;
 bool enabled;
 int id;
 enum max8997_led_mode led_mode;
 struct mutex mutex;
};

static void max8997_led_set_mode(struct max8997_led *led,
   enum max8997_led_mode mode)
{
 int ret;
 struct i2c_client *client = led->iodev->i2c;
 u8 mask = 0, val;

 switch (mode) {
 case MAX8997_FLASH_MODE:
  mask = MAX8997_LED1_FLASH_MASK | MAX8997_LED0_FLASH_MASK;
  val = led->id ?
        MAX8997_LED1_FLASH_MASK : MAX8997_LED0_FLASH_MASK;
  led->cdev.max_brightness = MAX8997_LED_FLASH_MAX_BRIGHTNESS;
  break;
 case MAX8997_MOVIE_MODE:
  mask = MAX8997_LED1_MOVIE_MASK | MAX8997_LED0_MOVIE_MASK;
  val = led->id ?
        MAX8997_LED1_MOVIE_MASK : MAX8997_LED0_MOVIE_MASK;
  led->cdev.max_brightness = MAX8997_LED_MOVIE_MAX_BRIGHTNESS;
  break;
 case MAX8997_FLASH_PIN_CONTROL_MODE:
  mask = MAX8997_LED1_FLASH_PIN_MASK |
         MAX8997_LED0_FLASH_PIN_MASK;
  val = led->id ?
        MAX8997_LED1_FLASH_PIN_MASK : MAX8997_LED0_FLASH_PIN_MASK;
  led->cdev.max_brightness = MAX8997_LED_FLASH_MAX_BRIGHTNESS;
  break;
 case MAX8997_MOVIE_PIN_CONTROL_MODE:
  mask = MAX8997_LED1_MOVIE_PIN_MASK |
         MAX8997_LED0_MOVIE_PIN_MASK;
  val = led->id ?
        MAX8997_LED1_MOVIE_PIN_MASK : MAX8997_LED0_MOVIE_PIN_MASK;
  led->cdev.max_brightness = MAX8997_LED_MOVIE_MAX_BRIGHTNESS;
  break;
 default:
  led->cdev.max_brightness = MAX8997_LED_NONE_MAX_BRIGHTNESS;
  break;
 }

 if (mask) {
  ret = max8997_update_reg(client, MAX8997_REG_LEN_CNTL, val,
      mask);
  if (ret)
   dev_err(led->iodev->dev,
    "failed to update register(%d)\n", ret);
 }

 led->led_mode = mode;
}

static void max8997_led_enable(struct max8997_led *led, bool enable)
{
 int ret;
 struct i2c_client *client = led->iodev->i2c;
 u8 val = 0, mask = MAX8997_LED_BOOST_ENABLE_MASK;

 if (led->enabled == enable)
  return;

 val = enable ? MAX8997_LED_BOOST_ENABLE_MASK : 0;

 ret = max8997_update_reg(client, MAX8997_REG_BOOST_CNTL, val, mask);
 if (ret)
  dev_err(led->iodev->dev,
   "failed to update register(%d)\n", ret);

 led->enabled = enable;
}

static void max8997_led_set_current(struct max8997_led *led,
    enum led_brightness value)
{
 int ret;
 struct i2c_client *client = led->iodev->i2c;
 u8 val = 0, mask = 0, reg = 0;

 switch (led->led_mode) {
 case MAX8997_FLASH_MODE:
 case MAX8997_FLASH_PIN_CONTROL_MODE:
  val = value << MAX8997_LED_FLASH_SHIFT;
  mask = MAX8997_LED_FLASH_CUR_MASK;
  reg = led->id ? MAX8997_REG_FLASH2_CUR : MAX8997_REG_FLASH1_CUR;
  break;
 case MAX8997_MOVIE_MODE:
 case MAX8997_MOVIE_PIN_CONTROL_MODE:
  val = value << MAX8997_LED_MOVIE_SHIFT;
  mask = MAX8997_LED_MOVIE_CUR_MASK;
  reg = MAX8997_REG_MOVIE_CUR;
  break;
 default:
  break;
 }

 if (mask) {
  ret = max8997_update_reg(client, reg, val, mask);
  if (ret)
   dev_err(led->iodev->dev,
    "failed to update register(%d)\n", ret);
 }
}

static void max8997_led_brightness_set(struct led_classdev *led_cdev,
    enum led_brightness value)
{
 struct max8997_led *led =
   container_of(led_cdev, struct max8997_led, cdev);

 if (value) {
  max8997_led_set_current(led, value);
  max8997_led_enable(led, true);
 } else {
  max8997_led_set_current(led, value);
  max8997_led_enable(led, false);
 }
}

static ssize_t mode_show(struct device *dev,
    struct device_attribute *attr, char *buf)
{
 struct led_classdev *led_cdev = dev_get_drvdata(dev);
 struct max8997_led *led =
   container_of(led_cdev, struct max8997_led, cdev);
 ssize_t ret = 0;

 mutex_lock(&led->mutex);

 switch (led->led_mode) {
 case MAX8997_FLASH_MODE:
  ret += sprintf(buf, "FLASH\n");
  break;
 case MAX8997_MOVIE_MODE:
  ret += sprintf(buf, "MOVIE\n");
  break;
 case MAX8997_FLASH_PIN_CONTROL_MODE:
  ret += sprintf(buf, "FLASH_PIN_CONTROL\n");
  break;
 case MAX8997_MOVIE_PIN_CONTROL_MODE:
  ret += sprintf(buf, "MOVIE_PIN_CONTROL\n");
  break;
 default:
  ret += sprintf(buf, "NONE\n");
  break;
 }

 mutex_unlock(&led->mutex);

 return ret;
}

static ssize_t mode_store(struct device *dev,
     struct device_attribute *attr,
     const char *buf, size_t size)
{
 struct led_classdev *led_cdev = dev_get_drvdata(dev);
 struct max8997_led *led =
   container_of(led_cdev, struct max8997_led, cdev);
 enum max8997_led_mode mode;

 mutex_lock(&led->mutex);

 if (!strncmp(buf, "FLASH_PIN_CONTROL", 17))
  mode = MAX8997_FLASH_PIN_CONTROL_MODE;
 else if (!strncmp(buf, "MOVIE_PIN_CONTROL", 17))
  mode = MAX8997_MOVIE_PIN_CONTROL_MODE;
 else if (!strncmp(buf, "FLASH", 5))
  mode = MAX8997_FLASH_MODE;
 else if (!strncmp(buf, "MOVIE", 5))
  mode = MAX8997_MOVIE_MODE;
 else
  mode = MAX8997_NONE;

 max8997_led_set_mode(led, mode);

 mutex_unlock(&led->mutex);

 return size;
}

static DEVICE_ATTR_RW(mode);

static struct attribute *max8997_attrs[] = {
 &dev_attr_mode.attr,
 NULL
};
ATTRIBUTE_GROUPS(max8997);

static int max8997_led_probe(struct platform_device *pdev)
{
 struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent);
 struct max8997_platform_data *pdata = dev_get_platdata(iodev->dev);
 struct max8997_led *led;
 char name[20];
 int ret = 0;

 led = devm_kzalloc(&pdev->dev, sizeof(*led), GFP_KERNEL);
 if (led == NULL)
  return -ENOMEM;

 led->id = pdev->id;
 snprintf(name, sizeof(name), "max8997-led%d", pdev->id);

 led->cdev.name = name;
 led->cdev.brightness_set = max8997_led_brightness_set;
 led->cdev.flags |= LED_CORE_SUSPENDRESUME;
 led->cdev.brightness = 0;
 led->cdev.groups = max8997_groups;
 led->iodev = iodev;

 /* initialize mode and brightness according to platform_data */
 if (pdata && pdata->led_pdata) {
  u8 mode = 0, brightness = 0;

  mode = pdata->led_pdata->mode[led->id];
  brightness = pdata->led_pdata->brightness[led->id];

  max8997_led_set_mode(led, mode);

  if (brightness > led->cdev.max_brightness)
   brightness = led->cdev.max_brightness;
  max8997_led_set_current(led, brightness);
  led->cdev.brightness = brightness;
 } else {
  max8997_led_set_mode(led, MAX8997_NONE);
  max8997_led_set_current(led, 0);
 }

 mutex_init(&led->mutex);

 ret = devm_led_classdev_register(&pdev->dev, &led->cdev);
 if (ret < 0)
  return ret;

 return 0;
}

static struct platform_driver max8997_led_driver = {
 .driver = {
  .name  = "max8997-led",
 },
 .probe  = max8997_led_probe,
};

module_platform_driver(max8997_led_driver);

MODULE_AUTHOR("Donggeun Kim ");
MODULE_DESCRIPTION("MAX8997 LED driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:max8997-led");

Messung V0.5
C=94 H=89 G=91

¤ Dauer der Verarbeitung: 0.3 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.