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

Quelle  tps65217_bl.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-only
/*
 * tps65217_bl.c
 *
 * TPS65217 backlight driver
 *
 * Copyright (C) 2012 Matthias Kaehlcke
 * Author: Matthias Kaehlcke <matthias@kaehlcke.net>
 */


#include <linux/kernel.h>
#include <linux/backlight.h>
#include <linux/err.h>
#include <linux/mfd/tps65217.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

struct tps65217_bl {
 struct tps65217 *tps;
 struct device *dev;
 struct backlight_device *bl;
 bool is_enabled;
};

static int tps65217_bl_enable(struct tps65217_bl *tps65217_bl)
{
 int rc;

 rc = tps65217_set_bits(tps65217_bl->tps, TPS65217_REG_WLEDCTRL1,
   TPS65217_WLEDCTRL1_ISINK_ENABLE,
   TPS65217_WLEDCTRL1_ISINK_ENABLE, TPS65217_PROTECT_NONE);
 if (rc) {
  dev_err(tps65217_bl->dev,
   "failed to enable backlight: %d\n", rc);
  return rc;
 }

 tps65217_bl->is_enabled = true;

 dev_dbg(tps65217_bl->dev, "backlight enabled\n");

 return 0;
}

static int tps65217_bl_disable(struct tps65217_bl *tps65217_bl)
{
 int rc;

 rc = tps65217_clear_bits(tps65217_bl->tps,
    TPS65217_REG_WLEDCTRL1,
    TPS65217_WLEDCTRL1_ISINK_ENABLE,
    TPS65217_PROTECT_NONE);
 if (rc) {
  dev_err(tps65217_bl->dev,
   "failed to disable backlight: %d\n", rc);
  return rc;
 }

 tps65217_bl->is_enabled = false;

 dev_dbg(tps65217_bl->dev, "backlight disabled\n");

 return 0;
}

static int tps65217_bl_update_status(struct backlight_device *bl)
{
 struct tps65217_bl *tps65217_bl = bl_get_data(bl);
 int rc;
 int brightness = backlight_get_brightness(bl);

 if (brightness > 0) {
  rc = tps65217_reg_write(tps65217_bl->tps,
     TPS65217_REG_WLEDCTRL2,
     brightness - 1,
     TPS65217_PROTECT_NONE);
  if (rc) {
   dev_err(tps65217_bl->dev,
    "failed to set brightness level: %d\n", rc);
   return rc;
  }

  dev_dbg(tps65217_bl->dev, "brightness set to %d\n", brightness);

  if (!tps65217_bl->is_enabled)
   rc = tps65217_bl_enable(tps65217_bl);
 } else {
  rc = tps65217_bl_disable(tps65217_bl);
 }

 return rc;
}

static const struct backlight_ops tps65217_bl_ops = {
 .options = BL_CORE_SUSPENDRESUME,
 .update_status = tps65217_bl_update_status,
};

static int tps65217_bl_hw_init(struct tps65217_bl *tps65217_bl,
   struct tps65217_bl_pdata *pdata)
{
 int rc;

 rc = tps65217_bl_disable(tps65217_bl);
 if (rc)
  return rc;

 switch (pdata->isel) {
 case TPS65217_BL_ISET1:
  /* select ISET_1 current level */
  rc = tps65217_clear_bits(tps65217_bl->tps,
     TPS65217_REG_WLEDCTRL1,
     TPS65217_WLEDCTRL1_ISEL,
     TPS65217_PROTECT_NONE);
  if (rc) {
   dev_err(tps65217_bl->dev,
    "failed to select ISET1 current level: %d)\n",
    rc);
   return rc;
  }

  dev_dbg(tps65217_bl->dev, "selected ISET1 current level\n");

  break;

 case TPS65217_BL_ISET2:
  /* select ISET2 current level */
  rc = tps65217_set_bits(tps65217_bl->tps, TPS65217_REG_WLEDCTRL1,
    TPS65217_WLEDCTRL1_ISEL,
    TPS65217_WLEDCTRL1_ISEL, TPS65217_PROTECT_NONE);
  if (rc) {
   dev_err(tps65217_bl->dev,
    "failed to select ISET2 current level: %d\n",
    rc);
   return rc;
  }

  dev_dbg(tps65217_bl->dev, "selected ISET2 current level\n");

  break;

 default:
  dev_err(tps65217_bl->dev,
   "invalid value for current level: %d\n", pdata->isel);
  return -EINVAL;
 }

 /* set PWM frequency */
 rc = tps65217_set_bits(tps65217_bl->tps,
   TPS65217_REG_WLEDCTRL1,
   TPS65217_WLEDCTRL1_FDIM_MASK,
   pdata->fdim,
   TPS65217_PROTECT_NONE);
 if (rc) {
  dev_err(tps65217_bl->dev,
   "failed to select PWM dimming frequency: %d\n",
   rc);
  return rc;
 }

 return 0;
}

#ifdef CONFIG_OF
static struct tps65217_bl_pdata *
tps65217_bl_parse_dt(struct platform_device *pdev)
{
 struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent);
 struct device_node *node;
 struct tps65217_bl_pdata *pdata, *err;
 u32 val;

 node = of_get_child_by_name(tps->dev->of_node, "backlight");
 if (!node)
  return ERR_PTR(-ENODEV);

 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
 if (!pdata) {
  err = ERR_PTR(-ENOMEM);
  goto err;
 }

 pdata->isel = TPS65217_BL_ISET1;
 if (!of_property_read_u32(node, "isel", &val)) {
  if (val < TPS65217_BL_ISET1 ||
   val > TPS65217_BL_ISET2) {
   dev_err(&pdev->dev,
    "invalid 'isel' value in the device tree\n");
   err = ERR_PTR(-EINVAL);
   goto err;
  }

  pdata->isel = val;
 }

 pdata->fdim = TPS65217_BL_FDIM_200HZ;
 if (!of_property_read_u32(node, "fdim", &val)) {
  switch (val) {
  case 100:
   pdata->fdim = TPS65217_BL_FDIM_100HZ;
   break;

  case 200:
   pdata->fdim = TPS65217_BL_FDIM_200HZ;
   break;

  case 500:
   pdata->fdim = TPS65217_BL_FDIM_500HZ;
   break;

  case 1000:
   pdata->fdim = TPS65217_BL_FDIM_1000HZ;
   break;

  default:
   dev_err(&pdev->dev,
    "invalid 'fdim' value in the device tree\n");
   err = ERR_PTR(-EINVAL);
   goto err;
  }
 }

 if (!of_property_read_u32(node, "default-brightness", &val)) {
  if (val > 100) {
   dev_err(&pdev->dev,
    "invalid 'default-brightness' value in the device tree\n");
   err = ERR_PTR(-EINVAL);
   goto err;
  }

  pdata->dft_brightness = val;
 }

 of_node_put(node);

 return pdata;

err:
 of_node_put(node);

 return err;
}
#else
static struct tps65217_bl_pdata *
tps65217_bl_parse_dt(struct platform_device *pdev)
{
 return NULL;
}
#endif

static int tps65217_bl_probe(struct platform_device *pdev)
{
 int rc;
 struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent);
 struct tps65217_bl *tps65217_bl;
 struct tps65217_bl_pdata *pdata;
 struct backlight_properties bl_props;

 pdata = tps65217_bl_parse_dt(pdev);
 if (IS_ERR(pdata))
  return PTR_ERR(pdata);

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

 tps65217_bl->tps = tps;
 tps65217_bl->dev = &pdev->dev;
 tps65217_bl->is_enabled = false;

 rc = tps65217_bl_hw_init(tps65217_bl, pdata);
 if (rc)
  return rc;

 memset(&bl_props, 0, sizeof(struct backlight_properties));
 bl_props.type = BACKLIGHT_RAW;
 bl_props.max_brightness = 100;

 tps65217_bl->bl = devm_backlight_device_register(&pdev->dev, pdev->name,
      tps65217_bl->dev, tps65217_bl,
      &tps65217_bl_ops, &bl_props);
 if (IS_ERR(tps65217_bl->bl)) {
  dev_err(tps65217_bl->dev,
   "registration of backlight device failed: %d\n", rc);
  return PTR_ERR(tps65217_bl->bl);
 }

 tps65217_bl->bl->props.brightness = pdata->dft_brightness;
 backlight_update_status(tps65217_bl->bl);
 platform_set_drvdata(pdev, tps65217_bl);

 return 0;
}

#ifdef CONFIG_OF
static const struct of_device_id tps65217_bl_of_match[] = {
 { .compatible = "ti,tps65217-bl", },
 { /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, tps65217_bl_of_match);
#endif

static struct platform_driver tps65217_bl_driver = {
 .probe  = tps65217_bl_probe,
 .driver  = {
  .name = "tps65217-bl",
  .of_match_table = of_match_ptr(tps65217_bl_of_match),
 },
};

module_platform_driver(tps65217_bl_driver);

MODULE_DESCRIPTION("TPS65217 Backlight driver");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Matthias Kaehlcke ");

Messung V0.5
C=96 H=94 G=94

¤ Dauer der Verarbeitung: 0.12 Sekunden  (vorverarbeitet)  ¤

*© 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.