root/drivers/leds/leds-max77650.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. max77650_to_led
  2. max77650_led_brightness_set
  3. max77650_led_probe

   1 // SPDX-License-Identifier: GPL-2.0
   2 //
   3 // Copyright (C) 2018 BayLibre SAS
   4 // Author: Bartosz Golaszewski <bgolaszewski@baylibre.com>
   5 //
   6 // LED driver for MAXIM 77650/77651 charger/power-supply.
   7 
   8 #include <linux/i2c.h>
   9 #include <linux/leds.h>
  10 #include <linux/mfd/max77650.h>
  11 #include <linux/module.h>
  12 #include <linux/platform_device.h>
  13 #include <linux/regmap.h>
  14 
  15 #define MAX77650_LED_NUM_LEDS           3
  16 
  17 #define MAX77650_LED_A_BASE             0x40
  18 #define MAX77650_LED_B_BASE             0x43
  19 
  20 #define MAX77650_LED_BR_MASK            GENMASK(4, 0)
  21 #define MAX77650_LED_EN_MASK            GENMASK(7, 6)
  22 
  23 #define MAX77650_LED_MAX_BRIGHTNESS     MAX77650_LED_BR_MASK
  24 
  25 /* Enable EN_LED_MSTR. */
  26 #define MAX77650_LED_TOP_DEFAULT        BIT(0)
  27 
  28 #define MAX77650_LED_ENABLE             GENMASK(7, 6)
  29 #define MAX77650_LED_DISABLE            0x00
  30 
  31 #define MAX77650_LED_A_DEFAULT          MAX77650_LED_DISABLE
  32 /* 100% on duty */
  33 #define MAX77650_LED_B_DEFAULT          GENMASK(3, 0)
  34 
  35 struct max77650_led {
  36         struct led_classdev cdev;
  37         struct regmap *map;
  38         unsigned int regA;
  39         unsigned int regB;
  40 };
  41 
  42 static struct max77650_led *max77650_to_led(struct led_classdev *cdev)
  43 {
  44         return container_of(cdev, struct max77650_led, cdev);
  45 }
  46 
  47 static int max77650_led_brightness_set(struct led_classdev *cdev,
  48                                        enum led_brightness brightness)
  49 {
  50         struct max77650_led *led = max77650_to_led(cdev);
  51         int val, mask;
  52 
  53         mask = MAX77650_LED_BR_MASK | MAX77650_LED_EN_MASK;
  54 
  55         if (brightness == LED_OFF)
  56                 val = MAX77650_LED_DISABLE;
  57         else
  58                 val = MAX77650_LED_ENABLE | brightness;
  59 
  60         return regmap_update_bits(led->map, led->regA, mask, val);
  61 }
  62 
  63 static int max77650_led_probe(struct platform_device *pdev)
  64 {
  65         struct fwnode_handle *child;
  66         struct max77650_led *leds, *led;
  67         struct device *dev;
  68         struct regmap *map;
  69         const char *label;
  70         int rv, num_leds;
  71         u32 reg;
  72 
  73         dev = &pdev->dev;
  74 
  75         leds = devm_kcalloc(dev, sizeof(*leds),
  76                             MAX77650_LED_NUM_LEDS, GFP_KERNEL);
  77         if (!leds)
  78                 return -ENOMEM;
  79 
  80         map = dev_get_regmap(dev->parent, NULL);
  81         if (!map)
  82                 return -ENODEV;
  83 
  84         num_leds = device_get_child_node_count(dev);
  85         if (!num_leds || num_leds > MAX77650_LED_NUM_LEDS)
  86                 return -ENODEV;
  87 
  88         device_for_each_child_node(dev, child) {
  89                 rv = fwnode_property_read_u32(child, "reg", &reg);
  90                 if (rv || reg >= MAX77650_LED_NUM_LEDS) {
  91                         rv = -EINVAL;
  92                         goto err_node_put;
  93                 }
  94 
  95                 led = &leds[reg];
  96                 led->map = map;
  97                 led->regA = MAX77650_LED_A_BASE + reg;
  98                 led->regB = MAX77650_LED_B_BASE + reg;
  99                 led->cdev.brightness_set_blocking = max77650_led_brightness_set;
 100                 led->cdev.max_brightness = MAX77650_LED_MAX_BRIGHTNESS;
 101 
 102                 rv = fwnode_property_read_string(child, "label", &label);
 103                 if (rv) {
 104                         led->cdev.name = "max77650::";
 105                 } else {
 106                         led->cdev.name = devm_kasprintf(dev, GFP_KERNEL,
 107                                                         "max77650:%s", label);
 108                         if (!led->cdev.name) {
 109                                 rv = -ENOMEM;
 110                                 goto err_node_put;
 111                         }
 112                 }
 113 
 114                 fwnode_property_read_string(child, "linux,default-trigger",
 115                                             &led->cdev.default_trigger);
 116 
 117                 rv = devm_led_classdev_register(dev, &led->cdev);
 118                 if (rv)
 119                         goto err_node_put;
 120 
 121                 rv = regmap_write(map, led->regA, MAX77650_LED_A_DEFAULT);
 122                 if (rv)
 123                         goto err_node_put;
 124 
 125                 rv = regmap_write(map, led->regB, MAX77650_LED_B_DEFAULT);
 126                 if (rv)
 127                         goto err_node_put;
 128         }
 129 
 130         return regmap_write(map,
 131                             MAX77650_REG_CNFG_LED_TOP,
 132                             MAX77650_LED_TOP_DEFAULT);
 133 err_node_put:
 134         fwnode_handle_put(child);
 135         return rv;
 136 }
 137 
 138 static const struct of_device_id max77650_led_of_match[] = {
 139         { .compatible = "maxim,max77650-led" },
 140         { }
 141 };
 142 MODULE_DEVICE_TABLE(of, max77650_led_of_match);
 143 
 144 static struct platform_driver max77650_led_driver = {
 145         .driver = {
 146                 .name = "max77650-led",
 147                 .of_match_table = max77650_led_of_match,
 148         },
 149         .probe = max77650_led_probe,
 150 };
 151 module_platform_driver(max77650_led_driver);
 152 
 153 MODULE_DESCRIPTION("MAXIM 77650/77651 LED driver");
 154 MODULE_AUTHOR("Bartosz Golaszewski <bgolaszewski@baylibre.com>");
 155 MODULE_LICENSE("GPL v2");
 156 MODULE_ALIAS("platform:max77650-led");

/* [<][>][^][v][top][bottom][index][help] */