linux/drivers/mfd/lp3943.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * TI/National Semiconductor LP3943 MFD Core Driver
   4 *
   5 * Copyright 2013 Texas Instruments
   6 *
   7 * Author: Milo Kim <milo.kim@ti.com>
   8 *
   9 * Driver structure:
  10 *   LP3943 is an integrated device capable of driving 16 output channels.
  11 *   It can be used for a GPIO expander and PWM generators.
  12 *
  13 *                                   LED control    General usage for a device
  14 *                                   ___________   ____________________________
  15 *
  16 *   LP3943 MFD ---- GPIO expander    leds-gpio        eg) HW enable pin
  17 *               |
  18 *               --- PWM generator    leds-pwm         eg) PWM input
  19 *
  20 *   Internal two PWM channels are used for LED dimming effect.
  21 *   And each output pin can be used as a GPIO as well.
  22 *   The LED functionality can work with GPIOs or PWMs.
  23 *   LEDs can be controlled with legacy leds-gpio(static brightness) or
  24 *   leds-pwm drivers(dynamic brightness control).
  25 *   Alternatively, it can be used for generic GPIO and PWM controller.
  26 *   For example, a GPIO is HW enable pin of a device.
  27 *   A PWM is input pin of a backlight device.
  28 */
  29
  30#include <linux/err.h>
  31#include <linux/gpio.h>
  32#include <linux/i2c.h>
  33#include <linux/mfd/core.h>
  34#include <linux/mfd/lp3943.h>
  35#include <linux/module.h>
  36#include <linux/of.h>
  37#include <linux/slab.h>
  38
  39#define LP3943_MAX_REGISTERS            0x09
  40
  41/* Register configuration for pin MUX */
  42static const struct lp3943_reg_cfg lp3943_mux_cfg[] = {
  43        /* address, mask, shift */
  44        { LP3943_REG_MUX0, 0x03, 0 },
  45        { LP3943_REG_MUX0, 0x0C, 2 },
  46        { LP3943_REG_MUX0, 0x30, 4 },
  47        { LP3943_REG_MUX0, 0xC0, 6 },
  48        { LP3943_REG_MUX1, 0x03, 0 },
  49        { LP3943_REG_MUX1, 0x0C, 2 },
  50        { LP3943_REG_MUX1, 0x30, 4 },
  51        { LP3943_REG_MUX1, 0xC0, 6 },
  52        { LP3943_REG_MUX2, 0x03, 0 },
  53        { LP3943_REG_MUX2, 0x0C, 2 },
  54        { LP3943_REG_MUX2, 0x30, 4 },
  55        { LP3943_REG_MUX2, 0xC0, 6 },
  56        { LP3943_REG_MUX3, 0x03, 0 },
  57        { LP3943_REG_MUX3, 0x0C, 2 },
  58        { LP3943_REG_MUX3, 0x30, 4 },
  59        { LP3943_REG_MUX3, 0xC0, 6 },
  60};
  61
  62static const struct mfd_cell lp3943_devs[] = {
  63        {
  64                .name = "lp3943-pwm",
  65                .of_compatible = "ti,lp3943-pwm",
  66        },
  67        {
  68                .name = "lp3943-gpio",
  69                .of_compatible = "ti,lp3943-gpio",
  70        },
  71};
  72
  73int lp3943_read_byte(struct lp3943 *lp3943, u8 reg, u8 *read)
  74{
  75        int ret;
  76        unsigned int val;
  77
  78        ret = regmap_read(lp3943->regmap, reg, &val);
  79        if (ret < 0)
  80                return ret;
  81
  82        *read = (u8)val;
  83        return 0;
  84}
  85EXPORT_SYMBOL_GPL(lp3943_read_byte);
  86
  87int lp3943_write_byte(struct lp3943 *lp3943, u8 reg, u8 data)
  88{
  89        return regmap_write(lp3943->regmap, reg, data);
  90}
  91EXPORT_SYMBOL_GPL(lp3943_write_byte);
  92
  93int lp3943_update_bits(struct lp3943 *lp3943, u8 reg, u8 mask, u8 data)
  94{
  95        return regmap_update_bits(lp3943->regmap, reg, mask, data);
  96}
  97EXPORT_SYMBOL_GPL(lp3943_update_bits);
  98
  99static const struct regmap_config lp3943_regmap_config = {
 100        .reg_bits = 8,
 101        .val_bits = 8,
 102        .max_register = LP3943_MAX_REGISTERS,
 103};
 104
 105static int lp3943_probe(struct i2c_client *cl, const struct i2c_device_id *id)
 106{
 107        struct lp3943 *lp3943;
 108        struct device *dev = &cl->dev;
 109
 110        lp3943 = devm_kzalloc(dev, sizeof(*lp3943), GFP_KERNEL);
 111        if (!lp3943)
 112                return -ENOMEM;
 113
 114        lp3943->regmap = devm_regmap_init_i2c(cl, &lp3943_regmap_config);
 115        if (IS_ERR(lp3943->regmap))
 116                return PTR_ERR(lp3943->regmap);
 117
 118        lp3943->pdata = dev_get_platdata(dev);
 119        lp3943->dev = dev;
 120        lp3943->mux_cfg = lp3943_mux_cfg;
 121        i2c_set_clientdata(cl, lp3943);
 122
 123        return devm_mfd_add_devices(dev, -1, lp3943_devs,
 124                                    ARRAY_SIZE(lp3943_devs),
 125                                    NULL, 0, NULL);
 126}
 127
 128static const struct i2c_device_id lp3943_ids[] = {
 129        { "lp3943", 0 },
 130        { }
 131};
 132MODULE_DEVICE_TABLE(i2c, lp3943_ids);
 133
 134#ifdef CONFIG_OF
 135static const struct of_device_id lp3943_of_match[] = {
 136        { .compatible = "ti,lp3943", },
 137        { }
 138};
 139MODULE_DEVICE_TABLE(of, lp3943_of_match);
 140#endif
 141
 142static struct i2c_driver lp3943_driver = {
 143        .probe = lp3943_probe,
 144        .driver = {
 145                .name = "lp3943",
 146                .of_match_table = of_match_ptr(lp3943_of_match),
 147        },
 148        .id_table = lp3943_ids,
 149};
 150
 151module_i2c_driver(lp3943_driver);
 152
 153MODULE_DESCRIPTION("LP3943 MFD Core Driver");
 154MODULE_AUTHOR("Milo Kim");
 155MODULE_LICENSE("GPL");
 156