Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  tps65217_bl.c  Sprache: unbekannt

 
// 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 <matthias@kaehlcke.net>");

Messung V0.5 in Prozent
C=99 H=94 G=96

[Dauer der Verarbeitung: 0.16 Sekunden, vorverarbeitet 2026-09-29]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Statistik
#Sources=1127926
#Domains=2039723