Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * TI/National Semiconductor LP3943 MFD Core Driver
0004  *
0005  * Copyright 2013 Texas Instruments
0006  *
0007  * Author: Milo Kim <milo.kim@ti.com>
0008  *
0009  * Driver structure:
0010  *   LP3943 is an integrated device capable of driving 16 output channels.
0011  *   It can be used for a GPIO expander and PWM generators.
0012  *
0013  *                                   LED control    General usage for a device
0014  *                                   ___________   ____________________________
0015  *
0016  *   LP3943 MFD ---- GPIO expander    leds-gpio        eg) HW enable pin
0017  *               |
0018  *               --- PWM generator    leds-pwm         eg) PWM input
0019  *
0020  *   Internal two PWM channels are used for LED dimming effect.
0021  *   And each output pin can be used as a GPIO as well.
0022  *   The LED functionality can work with GPIOs or PWMs.
0023  *   LEDs can be controlled with legacy leds-gpio(static brightness) or
0024  *   leds-pwm drivers(dynamic brightness control).
0025  *   Alternatively, it can be used for generic GPIO and PWM controller.
0026  *   For example, a GPIO is HW enable pin of a device.
0027  *   A PWM is input pin of a backlight device.
0028  */
0029 
0030 #include <linux/err.h>
0031 #include <linux/gpio.h>
0032 #include <linux/i2c.h>
0033 #include <linux/mfd/core.h>
0034 #include <linux/mfd/lp3943.h>
0035 #include <linux/module.h>
0036 #include <linux/of.h>
0037 #include <linux/slab.h>
0038 
0039 #define LP3943_MAX_REGISTERS        0x09
0040 
0041 /* Register configuration for pin MUX */
0042 static const struct lp3943_reg_cfg lp3943_mux_cfg[] = {
0043     /* address, mask, shift */
0044     { LP3943_REG_MUX0, 0x03, 0 },
0045     { LP3943_REG_MUX0, 0x0C, 2 },
0046     { LP3943_REG_MUX0, 0x30, 4 },
0047     { LP3943_REG_MUX0, 0xC0, 6 },
0048     { LP3943_REG_MUX1, 0x03, 0 },
0049     { LP3943_REG_MUX1, 0x0C, 2 },
0050     { LP3943_REG_MUX1, 0x30, 4 },
0051     { LP3943_REG_MUX1, 0xC0, 6 },
0052     { LP3943_REG_MUX2, 0x03, 0 },
0053     { LP3943_REG_MUX2, 0x0C, 2 },
0054     { LP3943_REG_MUX2, 0x30, 4 },
0055     { LP3943_REG_MUX2, 0xC0, 6 },
0056     { LP3943_REG_MUX3, 0x03, 0 },
0057     { LP3943_REG_MUX3, 0x0C, 2 },
0058     { LP3943_REG_MUX3, 0x30, 4 },
0059     { LP3943_REG_MUX3, 0xC0, 6 },
0060 };
0061 
0062 static const struct mfd_cell lp3943_devs[] = {
0063     {
0064         .name = "lp3943-pwm",
0065         .of_compatible = "ti,lp3943-pwm",
0066     },
0067     {
0068         .name = "lp3943-gpio",
0069         .of_compatible = "ti,lp3943-gpio",
0070     },
0071 };
0072 
0073 int lp3943_read_byte(struct lp3943 *lp3943, u8 reg, u8 *read)
0074 {
0075     int ret;
0076     unsigned int val;
0077 
0078     ret = regmap_read(lp3943->regmap, reg, &val);
0079     if (ret < 0)
0080         return ret;
0081 
0082     *read = (u8)val;
0083     return 0;
0084 }
0085 EXPORT_SYMBOL_GPL(lp3943_read_byte);
0086 
0087 int lp3943_write_byte(struct lp3943 *lp3943, u8 reg, u8 data)
0088 {
0089     return regmap_write(lp3943->regmap, reg, data);
0090 }
0091 EXPORT_SYMBOL_GPL(lp3943_write_byte);
0092 
0093 int lp3943_update_bits(struct lp3943 *lp3943, u8 reg, u8 mask, u8 data)
0094 {
0095     return regmap_update_bits(lp3943->regmap, reg, mask, data);
0096 }
0097 EXPORT_SYMBOL_GPL(lp3943_update_bits);
0098 
0099 static const struct regmap_config lp3943_regmap_config = {
0100     .reg_bits = 8,
0101     .val_bits = 8,
0102     .max_register = LP3943_MAX_REGISTERS,
0103 };
0104 
0105 static int lp3943_probe(struct i2c_client *cl, const struct i2c_device_id *id)
0106 {
0107     struct lp3943 *lp3943;
0108     struct device *dev = &cl->dev;
0109 
0110     lp3943 = devm_kzalloc(dev, sizeof(*lp3943), GFP_KERNEL);
0111     if (!lp3943)
0112         return -ENOMEM;
0113 
0114     lp3943->regmap = devm_regmap_init_i2c(cl, &lp3943_regmap_config);
0115     if (IS_ERR(lp3943->regmap))
0116         return PTR_ERR(lp3943->regmap);
0117 
0118     lp3943->pdata = dev_get_platdata(dev);
0119     lp3943->dev = dev;
0120     lp3943->mux_cfg = lp3943_mux_cfg;
0121     i2c_set_clientdata(cl, lp3943);
0122 
0123     return devm_mfd_add_devices(dev, -1, lp3943_devs,
0124                     ARRAY_SIZE(lp3943_devs),
0125                     NULL, 0, NULL);
0126 }
0127 
0128 static const struct i2c_device_id lp3943_ids[] = {
0129     { "lp3943", 0 },
0130     { }
0131 };
0132 MODULE_DEVICE_TABLE(i2c, lp3943_ids);
0133 
0134 #ifdef CONFIG_OF
0135 static const struct of_device_id lp3943_of_match[] = {
0136     { .compatible = "ti,lp3943", },
0137     { }
0138 };
0139 MODULE_DEVICE_TABLE(of, lp3943_of_match);
0140 #endif
0141 
0142 static struct i2c_driver lp3943_driver = {
0143     .probe = lp3943_probe,
0144     .driver = {
0145         .name = "lp3943",
0146         .of_match_table = of_match_ptr(lp3943_of_match),
0147     },
0148     .id_table = lp3943_ids,
0149 };
0150 
0151 module_i2c_driver(lp3943_driver);
0152 
0153 MODULE_DESCRIPTION("LP3943 MFD Core Driver");
0154 MODULE_AUTHOR("Milo Kim");
0155 MODULE_LICENSE("GPL");