xref: /openbmc/linux/drivers/mfd/lp3943.c (revision 9816d859)
1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2470eca47SMilo Kim /*
3470eca47SMilo Kim  * TI/National Semiconductor LP3943 MFD Core Driver
4470eca47SMilo Kim  *
5470eca47SMilo Kim  * Copyright 2013 Texas Instruments
6470eca47SMilo Kim  *
7470eca47SMilo Kim  * Author: Milo Kim <milo.kim@ti.com>
8470eca47SMilo Kim  *
9470eca47SMilo Kim  * Driver structure:
10470eca47SMilo Kim  *   LP3943 is an integrated device capable of driving 16 output channels.
11470eca47SMilo Kim  *   It can be used for a GPIO expander and PWM generators.
12470eca47SMilo Kim  *
13470eca47SMilo Kim  *                                   LED control    General usage for a device
14470eca47SMilo Kim  *                                   ___________   ____________________________
15470eca47SMilo Kim  *
16470eca47SMilo Kim  *   LP3943 MFD ---- GPIO expander    leds-gpio        eg) HW enable pin
17470eca47SMilo Kim  *               |
18470eca47SMilo Kim  *               --- PWM generator    leds-pwm         eg) PWM input
19470eca47SMilo Kim  *
20470eca47SMilo Kim  *   Internal two PWM channels are used for LED dimming effect.
21470eca47SMilo Kim  *   And each output pin can be used as a GPIO as well.
22470eca47SMilo Kim  *   The LED functionality can work with GPIOs or PWMs.
23470eca47SMilo Kim  *   LEDs can be controlled with legacy leds-gpio(static brightness) or
24470eca47SMilo Kim  *   leds-pwm drivers(dynamic brightness control).
25470eca47SMilo Kim  *   Alternatively, it can be used for generic GPIO and PWM controller.
26470eca47SMilo Kim  *   For example, a GPIO is HW enable pin of a device.
27470eca47SMilo Kim  *   A PWM is input pin of a backlight device.
28470eca47SMilo Kim  */
29470eca47SMilo Kim 
30470eca47SMilo Kim #include <linux/err.h>
31470eca47SMilo Kim #include <linux/gpio.h>
32470eca47SMilo Kim #include <linux/i2c.h>
33470eca47SMilo Kim #include <linux/mfd/core.h>
34470eca47SMilo Kim #include <linux/mfd/lp3943.h>
35470eca47SMilo Kim #include <linux/module.h>
36470eca47SMilo Kim #include <linux/of.h>
37470eca47SMilo Kim #include <linux/slab.h>
38470eca47SMilo Kim 
39470eca47SMilo Kim #define LP3943_MAX_REGISTERS		0x09
40470eca47SMilo Kim 
41470eca47SMilo Kim /* Register configuration for pin MUX */
42470eca47SMilo Kim static const struct lp3943_reg_cfg lp3943_mux_cfg[] = {
43470eca47SMilo Kim 	/* address, mask, shift */
44470eca47SMilo Kim 	{ LP3943_REG_MUX0, 0x03, 0 },
45470eca47SMilo Kim 	{ LP3943_REG_MUX0, 0x0C, 2 },
46470eca47SMilo Kim 	{ LP3943_REG_MUX0, 0x30, 4 },
47470eca47SMilo Kim 	{ LP3943_REG_MUX0, 0xC0, 6 },
48470eca47SMilo Kim 	{ LP3943_REG_MUX1, 0x03, 0 },
49470eca47SMilo Kim 	{ LP3943_REG_MUX1, 0x0C, 2 },
50470eca47SMilo Kim 	{ LP3943_REG_MUX1, 0x30, 4 },
51470eca47SMilo Kim 	{ LP3943_REG_MUX1, 0xC0, 6 },
52470eca47SMilo Kim 	{ LP3943_REG_MUX2, 0x03, 0 },
53470eca47SMilo Kim 	{ LP3943_REG_MUX2, 0x0C, 2 },
54470eca47SMilo Kim 	{ LP3943_REG_MUX2, 0x30, 4 },
55470eca47SMilo Kim 	{ LP3943_REG_MUX2, 0xC0, 6 },
56470eca47SMilo Kim 	{ LP3943_REG_MUX3, 0x03, 0 },
57470eca47SMilo Kim 	{ LP3943_REG_MUX3, 0x0C, 2 },
58470eca47SMilo Kim 	{ LP3943_REG_MUX3, 0x30, 4 },
59470eca47SMilo Kim 	{ LP3943_REG_MUX3, 0xC0, 6 },
60470eca47SMilo Kim };
61470eca47SMilo Kim 
6281cf4f2dSKrzysztof Kozlowski static const struct mfd_cell lp3943_devs[] = {
63470eca47SMilo Kim 	{
64470eca47SMilo Kim 		.name = "lp3943-pwm",
65470eca47SMilo Kim 		.of_compatible = "ti,lp3943-pwm",
66470eca47SMilo Kim 	},
67470eca47SMilo Kim 	{
68470eca47SMilo Kim 		.name = "lp3943-gpio",
69470eca47SMilo Kim 		.of_compatible = "ti,lp3943-gpio",
70470eca47SMilo Kim 	},
71470eca47SMilo Kim };
72470eca47SMilo Kim 
lp3943_read_byte(struct lp3943 * lp3943,u8 reg,u8 * read)73470eca47SMilo Kim int lp3943_read_byte(struct lp3943 *lp3943, u8 reg, u8 *read)
74470eca47SMilo Kim {
75470eca47SMilo Kim 	int ret;
76470eca47SMilo Kim 	unsigned int val;
77470eca47SMilo Kim 
78470eca47SMilo Kim 	ret = regmap_read(lp3943->regmap, reg, &val);
79470eca47SMilo Kim 	if (ret < 0)
80470eca47SMilo Kim 		return ret;
81470eca47SMilo Kim 
82470eca47SMilo Kim 	*read = (u8)val;
83470eca47SMilo Kim 	return 0;
84470eca47SMilo Kim }
85470eca47SMilo Kim EXPORT_SYMBOL_GPL(lp3943_read_byte);
86470eca47SMilo Kim 
lp3943_write_byte(struct lp3943 * lp3943,u8 reg,u8 data)87470eca47SMilo Kim int lp3943_write_byte(struct lp3943 *lp3943, u8 reg, u8 data)
88470eca47SMilo Kim {
89470eca47SMilo Kim 	return regmap_write(lp3943->regmap, reg, data);
90470eca47SMilo Kim }
91470eca47SMilo Kim EXPORT_SYMBOL_GPL(lp3943_write_byte);
92470eca47SMilo Kim 
lp3943_update_bits(struct lp3943 * lp3943,u8 reg,u8 mask,u8 data)93470eca47SMilo Kim int lp3943_update_bits(struct lp3943 *lp3943, u8 reg, u8 mask, u8 data)
94470eca47SMilo Kim {
95470eca47SMilo Kim 	return regmap_update_bits(lp3943->regmap, reg, mask, data);
96470eca47SMilo Kim }
97470eca47SMilo Kim EXPORT_SYMBOL_GPL(lp3943_update_bits);
98470eca47SMilo Kim 
99470eca47SMilo Kim static const struct regmap_config lp3943_regmap_config = {
100470eca47SMilo Kim 	.reg_bits = 8,
101470eca47SMilo Kim 	.val_bits = 8,
102470eca47SMilo Kim 	.max_register = LP3943_MAX_REGISTERS,
103470eca47SMilo Kim };
104470eca47SMilo Kim 
lp3943_probe(struct i2c_client * cl)105f7b497cbSUwe Kleine-König static int lp3943_probe(struct i2c_client *cl)
106470eca47SMilo Kim {
107470eca47SMilo Kim 	struct lp3943 *lp3943;
108470eca47SMilo Kim 	struct device *dev = &cl->dev;
109470eca47SMilo Kim 
110470eca47SMilo Kim 	lp3943 = devm_kzalloc(dev, sizeof(*lp3943), GFP_KERNEL);
111470eca47SMilo Kim 	if (!lp3943)
112470eca47SMilo Kim 		return -ENOMEM;
113470eca47SMilo Kim 
114470eca47SMilo Kim 	lp3943->regmap = devm_regmap_init_i2c(cl, &lp3943_regmap_config);
115470eca47SMilo Kim 	if (IS_ERR(lp3943->regmap))
116470eca47SMilo Kim 		return PTR_ERR(lp3943->regmap);
117470eca47SMilo Kim 
118470eca47SMilo Kim 	lp3943->pdata = dev_get_platdata(dev);
119470eca47SMilo Kim 	lp3943->dev = dev;
120470eca47SMilo Kim 	lp3943->mux_cfg = lp3943_mux_cfg;
121470eca47SMilo Kim 	i2c_set_clientdata(cl, lp3943);
122470eca47SMilo Kim 
123c5f24454SLaxman Dewangan 	return devm_mfd_add_devices(dev, -1, lp3943_devs,
124c5f24454SLaxman Dewangan 				    ARRAY_SIZE(lp3943_devs),
125470eca47SMilo Kim 				    NULL, 0, NULL);
126470eca47SMilo Kim }
127470eca47SMilo Kim 
128470eca47SMilo Kim static const struct i2c_device_id lp3943_ids[] = {
129470eca47SMilo Kim 	{ "lp3943", 0 },
130470eca47SMilo Kim 	{ }
131470eca47SMilo Kim };
132470eca47SMilo Kim MODULE_DEVICE_TABLE(i2c, lp3943_ids);
133470eca47SMilo Kim 
134470eca47SMilo Kim #ifdef CONFIG_OF
135470eca47SMilo Kim static const struct of_device_id lp3943_of_match[] = {
136470eca47SMilo Kim 	{ .compatible = "ti,lp3943", },
137470eca47SMilo Kim 	{ }
138470eca47SMilo Kim };
139470eca47SMilo Kim MODULE_DEVICE_TABLE(of, lp3943_of_match);
140470eca47SMilo Kim #endif
141470eca47SMilo Kim 
142470eca47SMilo Kim static struct i2c_driver lp3943_driver = {
143*9816d859SUwe Kleine-König 	.probe = lp3943_probe,
144470eca47SMilo Kim 	.driver = {
145470eca47SMilo Kim 		.name = "lp3943",
146470eca47SMilo Kim 		.of_match_table = of_match_ptr(lp3943_of_match),
147470eca47SMilo Kim 	},
148470eca47SMilo Kim 	.id_table = lp3943_ids,
149470eca47SMilo Kim };
150470eca47SMilo Kim 
151470eca47SMilo Kim module_i2c_driver(lp3943_driver);
152470eca47SMilo Kim 
153470eca47SMilo Kim MODULE_DESCRIPTION("LP3943 MFD Core Driver");
154470eca47SMilo Kim MODULE_AUTHOR("Milo Kim");
155470eca47SMilo Kim MODULE_LICENSE("GPL");
156