diff options
author | Milo Kim <milo.kim@ti.com> | 2013-12-05 21:18:41 -0500 |
---|---|---|
committer | Lee Jones <lee.jones@linaro.org> | 2014-01-21 03:27:59 -0500 |
commit | 470eca47bded10f2e1a425b44d6f2b1418271a9f (patch) | |
tree | 9e302eabaeb9fd2edd3dfd3c28d821c109f60487 | |
parent | 0cc59b9d98d554168915b3765a14e8b4ad75918c (diff) |
mfd: Add LP3943 MFD driver
LP3943 has 16 output pins which can be used as GPIO expander and PWM generator.
* Regmap I2C interface for R/W LP3943 registers
* Atomic operations for output pin assignment
The driver should check whether requested pin is available or not.
If the pin is already used, pin request returns as a failure.
A driver data, 'pin_used' is checked when gpio_request() and
pwm_request() are called. If the pin is available, then pin_used is set.
And it is cleared when gpio_free() and pwm_free().
* Device tree support
Compatible strings for GPIO and PWM driver.
LP3943 platform data is PWM related, so parsing the device tree is
implemented in the PWM driver.
Signed-off-by: Milo Kim <milo.kim@ti.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
-rw-r--r-- | drivers/mfd/Kconfig | 11 | ||||
-rw-r--r-- | drivers/mfd/Makefile | 1 | ||||
-rw-r--r-- | drivers/mfd/lp3943.c | 167 | ||||
-rw-r--r-- | include/linux/mfd/lp3943.h | 114 |
4 files changed, 293 insertions, 0 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index e54a6fd2a5bd..1c2a389e6dc2 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig | |||
@@ -738,6 +738,17 @@ config MFD_DM355EVM_MSP | |||
738 | boards. MSP430 firmware manages resets and power sequencing, | 738 | boards. MSP430 firmware manages resets and power sequencing, |
739 | inputs from buttons and the IR remote, LEDs, an RTC, and more. | 739 | inputs from buttons and the IR remote, LEDs, an RTC, and more. |
740 | 740 | ||
741 | config MFD_LP3943 | ||
742 | tristate "TI/National Semiconductor LP3943 MFD Driver" | ||
743 | depends on I2C | ||
744 | select MFD_CORE | ||
745 | select REGMAP_I2C | ||
746 | help | ||
747 | Support for the TI/National Semiconductor LP3943. | ||
748 | This driver consists of GPIO and PWM drivers. | ||
749 | With these functionalities, it can be used for LED string control or | ||
750 | general usage such like a GPIO controller and a PWM controller. | ||
751 | |||
741 | config MFD_LP8788 | 752 | config MFD_LP8788 |
742 | bool "TI LP8788 Power Management Unit Driver" | 753 | bool "TI LP8788 Power Management Unit Driver" |
743 | depends on I2C=y | 754 | depends on I2C=y |
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 2e18b05017d9..5aea5ef0a62f 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile | |||
@@ -102,6 +102,7 @@ obj-$(CONFIG_PMIC_DA9052) += da9052-core.o | |||
102 | obj-$(CONFIG_MFD_DA9052_SPI) += da9052-spi.o | 102 | obj-$(CONFIG_MFD_DA9052_SPI) += da9052-spi.o |
103 | obj-$(CONFIG_MFD_DA9052_I2C) += da9052-i2c.o | 103 | obj-$(CONFIG_MFD_DA9052_I2C) += da9052-i2c.o |
104 | 104 | ||
105 | obj-$(CONFIG_MFD_LP3943) += lp3943.o | ||
105 | obj-$(CONFIG_MFD_LP8788) += lp8788.o lp8788-irq.o | 106 | obj-$(CONFIG_MFD_LP8788) += lp8788.o lp8788-irq.o |
106 | 107 | ||
107 | da9055-objs := da9055-core.o da9055-i2c.o | 108 | da9055-objs := da9055-core.o da9055-i2c.o |
diff --git a/drivers/mfd/lp3943.c b/drivers/mfd/lp3943.c new file mode 100644 index 000000000000..e32226836fb4 --- /dev/null +++ b/drivers/mfd/lp3943.c | |||
@@ -0,0 +1,167 @@ | |||
1 | /* | ||
2 | * TI/National Semiconductor LP3943 MFD Core Driver | ||
3 | * | ||
4 | * Copyright 2013 Texas Instruments | ||
5 | * | ||
6 | * Author: Milo Kim <milo.kim@ti.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | * Driver structure: | ||
13 | * LP3943 is an integrated device capable of driving 16 output channels. | ||
14 | * It can be used for a GPIO expander and PWM generators. | ||
15 | * | ||
16 | * LED control General usage for a device | ||
17 | * ___________ ____________________________ | ||
18 | * | ||
19 | * LP3943 MFD ---- GPIO expander leds-gpio eg) HW enable pin | ||
20 | * | | ||
21 | * --- PWM generator leds-pwm eg) PWM input | ||
22 | * | ||
23 | * Internal two PWM channels are used for LED dimming effect. | ||
24 | * And each output pin can be used as a GPIO as well. | ||
25 | * The LED functionality can work with GPIOs or PWMs. | ||
26 | * LEDs can be controlled with legacy leds-gpio(static brightness) or | ||
27 | * leds-pwm drivers(dynamic brightness control). | ||
28 | * Alternatively, it can be used for generic GPIO and PWM controller. | ||
29 | * For example, a GPIO is HW enable pin of a device. | ||
30 | * A PWM is input pin of a backlight device. | ||
31 | */ | ||
32 | |||
33 | #include <linux/err.h> | ||
34 | #include <linux/gpio.h> | ||
35 | #include <linux/i2c.h> | ||
36 | #include <linux/mfd/core.h> | ||
37 | #include <linux/mfd/lp3943.h> | ||
38 | #include <linux/module.h> | ||
39 | #include <linux/of.h> | ||
40 | #include <linux/slab.h> | ||
41 | |||
42 | #define LP3943_MAX_REGISTERS 0x09 | ||
43 | |||
44 | /* Register configuration for pin MUX */ | ||
45 | static const struct lp3943_reg_cfg lp3943_mux_cfg[] = { | ||
46 | /* address, mask, shift */ | ||
47 | { LP3943_REG_MUX0, 0x03, 0 }, | ||
48 | { LP3943_REG_MUX0, 0x0C, 2 }, | ||
49 | { LP3943_REG_MUX0, 0x30, 4 }, | ||
50 | { LP3943_REG_MUX0, 0xC0, 6 }, | ||
51 | { LP3943_REG_MUX1, 0x03, 0 }, | ||
52 | { LP3943_REG_MUX1, 0x0C, 2 }, | ||
53 | { LP3943_REG_MUX1, 0x30, 4 }, | ||
54 | { LP3943_REG_MUX1, 0xC0, 6 }, | ||
55 | { LP3943_REG_MUX2, 0x03, 0 }, | ||
56 | { LP3943_REG_MUX2, 0x0C, 2 }, | ||
57 | { LP3943_REG_MUX2, 0x30, 4 }, | ||
58 | { LP3943_REG_MUX2, 0xC0, 6 }, | ||
59 | { LP3943_REG_MUX3, 0x03, 0 }, | ||
60 | { LP3943_REG_MUX3, 0x0C, 2 }, | ||
61 | { LP3943_REG_MUX3, 0x30, 4 }, | ||
62 | { LP3943_REG_MUX3, 0xC0, 6 }, | ||
63 | }; | ||
64 | |||
65 | static struct mfd_cell lp3943_devs[] = { | ||
66 | { | ||
67 | .name = "lp3943-pwm", | ||
68 | .of_compatible = "ti,lp3943-pwm", | ||
69 | }, | ||
70 | { | ||
71 | .name = "lp3943-gpio", | ||
72 | .of_compatible = "ti,lp3943-gpio", | ||
73 | }, | ||
74 | }; | ||
75 | |||
76 | int lp3943_read_byte(struct lp3943 *lp3943, u8 reg, u8 *read) | ||
77 | { | ||
78 | int ret; | ||
79 | unsigned int val; | ||
80 | |||
81 | ret = regmap_read(lp3943->regmap, reg, &val); | ||
82 | if (ret < 0) | ||
83 | return ret; | ||
84 | |||
85 | *read = (u8)val; | ||
86 | return 0; | ||
87 | } | ||
88 | EXPORT_SYMBOL_GPL(lp3943_read_byte); | ||
89 | |||
90 | int lp3943_write_byte(struct lp3943 *lp3943, u8 reg, u8 data) | ||
91 | { | ||
92 | return regmap_write(lp3943->regmap, reg, data); | ||
93 | } | ||
94 | EXPORT_SYMBOL_GPL(lp3943_write_byte); | ||
95 | |||
96 | int lp3943_update_bits(struct lp3943 *lp3943, u8 reg, u8 mask, u8 data) | ||
97 | { | ||
98 | return regmap_update_bits(lp3943->regmap, reg, mask, data); | ||
99 | } | ||
100 | EXPORT_SYMBOL_GPL(lp3943_update_bits); | ||
101 | |||
102 | static const struct regmap_config lp3943_regmap_config = { | ||
103 | .reg_bits = 8, | ||
104 | .val_bits = 8, | ||
105 | .max_register = LP3943_MAX_REGISTERS, | ||
106 | }; | ||
107 | |||
108 | static int lp3943_probe(struct i2c_client *cl, const struct i2c_device_id *id) | ||
109 | { | ||
110 | struct lp3943 *lp3943; | ||
111 | struct device *dev = &cl->dev; | ||
112 | |||
113 | lp3943 = devm_kzalloc(dev, sizeof(*lp3943), GFP_KERNEL); | ||
114 | if (!lp3943) | ||
115 | return -ENOMEM; | ||
116 | |||
117 | lp3943->regmap = devm_regmap_init_i2c(cl, &lp3943_regmap_config); | ||
118 | if (IS_ERR(lp3943->regmap)) | ||
119 | return PTR_ERR(lp3943->regmap); | ||
120 | |||
121 | lp3943->pdata = dev_get_platdata(dev); | ||
122 | lp3943->dev = dev; | ||
123 | lp3943->mux_cfg = lp3943_mux_cfg; | ||
124 | i2c_set_clientdata(cl, lp3943); | ||
125 | |||
126 | return mfd_add_devices(dev, -1, lp3943_devs, ARRAY_SIZE(lp3943_devs), | ||
127 | NULL, 0, NULL); | ||
128 | } | ||
129 | |||
130 | static int lp3943_remove(struct i2c_client *cl) | ||
131 | { | ||
132 | struct lp3943 *lp3943 = i2c_get_clientdata(cl); | ||
133 | |||
134 | mfd_remove_devices(lp3943->dev); | ||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | static const struct i2c_device_id lp3943_ids[] = { | ||
139 | { "lp3943", 0 }, | ||
140 | { } | ||
141 | }; | ||
142 | MODULE_DEVICE_TABLE(i2c, lp3943_ids); | ||
143 | |||
144 | #ifdef CONFIG_OF | ||
145 | static const struct of_device_id lp3943_of_match[] = { | ||
146 | { .compatible = "ti,lp3943", }, | ||
147 | { } | ||
148 | }; | ||
149 | MODULE_DEVICE_TABLE(of, lp3943_of_match); | ||
150 | #endif | ||
151 | |||
152 | static struct i2c_driver lp3943_driver = { | ||
153 | .probe = lp3943_probe, | ||
154 | .remove = lp3943_remove, | ||
155 | .driver = { | ||
156 | .name = "lp3943", | ||
157 | .owner = THIS_MODULE, | ||
158 | .of_match_table = of_match_ptr(lp3943_of_match), | ||
159 | }, | ||
160 | .id_table = lp3943_ids, | ||
161 | }; | ||
162 | |||
163 | module_i2c_driver(lp3943_driver); | ||
164 | |||
165 | MODULE_DESCRIPTION("LP3943 MFD Core Driver"); | ||
166 | MODULE_AUTHOR("Milo Kim"); | ||
167 | MODULE_LICENSE("GPL"); | ||
diff --git a/include/linux/mfd/lp3943.h b/include/linux/mfd/lp3943.h new file mode 100644 index 000000000000..3490db782988 --- /dev/null +++ b/include/linux/mfd/lp3943.h | |||
@@ -0,0 +1,114 @@ | |||
1 | /* | ||
2 | * TI/National Semiconductor LP3943 Device | ||
3 | * | ||
4 | * Copyright 2013 Texas Instruments | ||
5 | * | ||
6 | * Author: Milo Kim <milo.kim@ti.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #ifndef __MFD_LP3943_H__ | ||
15 | #define __MFD_LP3943_H__ | ||
16 | |||
17 | #include <linux/gpio.h> | ||
18 | #include <linux/pwm.h> | ||
19 | #include <linux/regmap.h> | ||
20 | |||
21 | /* Registers */ | ||
22 | #define LP3943_REG_GPIO_A 0x00 | ||
23 | #define LP3943_REG_GPIO_B 0x01 | ||
24 | #define LP3943_REG_PRESCALE0 0x02 | ||
25 | #define LP3943_REG_PWM0 0x03 | ||
26 | #define LP3943_REG_PRESCALE1 0x04 | ||
27 | #define LP3943_REG_PWM1 0x05 | ||
28 | #define LP3943_REG_MUX0 0x06 | ||
29 | #define LP3943_REG_MUX1 0x07 | ||
30 | #define LP3943_REG_MUX2 0x08 | ||
31 | #define LP3943_REG_MUX3 0x09 | ||
32 | |||
33 | /* Bit description for LP3943_REG_MUX0 ~ 3 */ | ||
34 | #define LP3943_GPIO_IN 0x00 | ||
35 | #define LP3943_GPIO_OUT_HIGH 0x00 | ||
36 | #define LP3943_GPIO_OUT_LOW 0x01 | ||
37 | #define LP3943_DIM_PWM0 0x02 | ||
38 | #define LP3943_DIM_PWM1 0x03 | ||
39 | |||
40 | #define LP3943_NUM_PWMS 2 | ||
41 | |||
42 | enum lp3943_pwm_output { | ||
43 | LP3943_PWM_OUT0, | ||
44 | LP3943_PWM_OUT1, | ||
45 | LP3943_PWM_OUT2, | ||
46 | LP3943_PWM_OUT3, | ||
47 | LP3943_PWM_OUT4, | ||
48 | LP3943_PWM_OUT5, | ||
49 | LP3943_PWM_OUT6, | ||
50 | LP3943_PWM_OUT7, | ||
51 | LP3943_PWM_OUT8, | ||
52 | LP3943_PWM_OUT9, | ||
53 | LP3943_PWM_OUT10, | ||
54 | LP3943_PWM_OUT11, | ||
55 | LP3943_PWM_OUT12, | ||
56 | LP3943_PWM_OUT13, | ||
57 | LP3943_PWM_OUT14, | ||
58 | LP3943_PWM_OUT15, | ||
59 | }; | ||
60 | |||
61 | /* | ||
62 | * struct lp3943_pwm_map | ||
63 | * @output: Output pins which are mapped to each PWM channel | ||
64 | * @num_outputs: Number of outputs | ||
65 | */ | ||
66 | struct lp3943_pwm_map { | ||
67 | enum lp3943_pwm_output *output; | ||
68 | int num_outputs; | ||
69 | }; | ||
70 | |||
71 | /* | ||
72 | * struct lp3943_platform_data | ||
73 | * @pwms: Output channel definitions for PWM channel 0 and 1 | ||
74 | */ | ||
75 | struct lp3943_platform_data { | ||
76 | struct lp3943_pwm_map *pwms[LP3943_NUM_PWMS]; | ||
77 | }; | ||
78 | |||
79 | /* | ||
80 | * struct lp3943_reg_cfg | ||
81 | * @reg: Register address | ||
82 | * @mask: Register bit mask to be updated | ||
83 | * @shift: Register bit shift | ||
84 | */ | ||
85 | struct lp3943_reg_cfg { | ||
86 | u8 reg; | ||
87 | u8 mask; | ||
88 | u8 shift; | ||
89 | }; | ||
90 | |||
91 | /* | ||
92 | * struct lp3943 | ||
93 | * @dev: Parent device pointer | ||
94 | * @regmap: Used for I2C communication on accessing registers | ||
95 | * @pdata: LP3943 platform specific data | ||
96 | * @mux_cfg: Register configuration for pin MUX | ||
97 | * @pin_used: Bit mask for output pin used. | ||
98 | * This bitmask is used for pin assignment management. | ||
99 | * 1 = pin used, 0 = available. | ||
100 | * Only LSB 16 bits are used, but it is unsigned long type | ||
101 | * for atomic bitwise operations. | ||
102 | */ | ||
103 | struct lp3943 { | ||
104 | struct device *dev; | ||
105 | struct regmap *regmap; | ||
106 | struct lp3943_platform_data *pdata; | ||
107 | const struct lp3943_reg_cfg *mux_cfg; | ||
108 | unsigned long pin_used; | ||
109 | }; | ||
110 | |||
111 | int lp3943_read_byte(struct lp3943 *lp3943, u8 reg, u8 *read); | ||
112 | int lp3943_write_byte(struct lp3943 *lp3943, u8 reg, u8 data); | ||
113 | int lp3943_update_bits(struct lp3943 *lp3943, u8 reg, u8 mask, u8 data); | ||
114 | #endif | ||