diff options
author | Robby Cai <R63905@freescale.com> | 2013-08-13 22:14:26 -0400 |
---|---|---|
committer | Nitin Garg <nitin.garg@freescale.com> | 2014-04-16 09:01:34 -0400 |
commit | 204ee4b0312a3dcfa84e196f3981d10a9017e462 (patch) | |
tree | fbfdec23f813858b4fd784eee2e786fd133e6c9e | |
parent | 3133b6cfb31b202805d31d449bfa70383e5e1c75 (diff) |
ENGR00276832-1 pmic: max17135: port driver codes to 3.10 kernel
It's ported from v3.5.7 kernel, which contains a sensor driver
and regulator driver. It's used for E-Ink panel.
add a parameter for mfd_add_devices() due to the propotype change.
use IS_ERR() to check the return value for devm_regulator_get().
Signed-off-by: Robby Cai <R63905@freescale.com>
-rw-r--r-- | Documentation/devicetree/bindings/regulator/max17135-regulator.txt | 112 | ||||
-rw-r--r-- | drivers/hwmon/Kconfig | 9 | ||||
-rw-r--r-- | drivers/hwmon/Makefile | 1 | ||||
-rw-r--r-- | drivers/hwmon/max17135-hwmon.c | 176 | ||||
-rw-r--r-- | drivers/mfd/Kconfig | 7 | ||||
-rw-r--r-- | drivers/mfd/Makefile | 1 | ||||
-rw-r--r-- | drivers/mfd/max17135-core.c | 295 | ||||
-rw-r--r-- | drivers/regulator/Kconfig | 4 | ||||
-rw-r--r-- | drivers/regulator/Makefile | 1 | ||||
-rw-r--r-- | drivers/regulator/max17135-regulator.c | 838 | ||||
-rw-r--r-- | include/linux/mfd/max17135.h | 220 | ||||
-rw-r--r-- | include/linux/pmic_status.h | 82 |
12 files changed, 1746 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/regulator/max17135-regulator.txt b/Documentation/devicetree/bindings/regulator/max17135-regulator.txt new file mode 100644 index 000000000000..c6e8eb663c49 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/max17135-regulator.txt | |||
@@ -0,0 +1,112 @@ | |||
1 | Maxim MAX17135 Voltage Regulator | ||
2 | |||
3 | The MAX17135 is a complete power-management IC for E-paper displays that | ||
4 | provides source- and gate-driver power supplies, a high-speed VCOM amplifier, | ||
5 | and a temperature sensor. It is interfaced to the host controller using an | ||
6 | i2c interface. | ||
7 | |||
8 | Required properties : | ||
9 | - compatible : "maxim,max17135" | ||
10 | - reg: Specifies the i2c slave address of the pmic block. | ||
11 | - vneg_pwrup: the timing for VNEG power up | ||
12 | - gvee_pwrup: the timing for GVEE power up | ||
13 | - vpos_pwrup: the timing for VPOS power up | ||
14 | - gvdd_pwrup: the timing for GVDD power up | ||
15 | - gvdd_pwrdn: the timing for GVDD power down | ||
16 | - vpos_pwrdn: the timing for VPOS power down | ||
17 | - gvee_pwrdn: the timing for GVEE power down | ||
18 | - vneg_pwrdn: the timing for VNEG power down | ||
19 | - gpio_pmic_pwrgood: gpio setting for EPDC_PWRSTAT | ||
20 | - gpio_pmic_vcom_ctrl: gpio setting for EPDC_VCOM | ||
21 | - gpio_pmic_wakeup: gpio setting for EPDC_PWRWAKEUP | ||
22 | - gpio_pmic_v3p3: gpio setting for EPDC_PWRCTRL0 | ||
23 | - gpio_pmic_intr: gpio setting for EPDC_PWRINT | ||
24 | |||
25 | Optional properties : | ||
26 | - SENSOR-supply: the gpio regulator to control the supply for this chip | ||
27 | |||
28 | |||
29 | Regulators: The regulators of max17135 that have to be instantiated should be | ||
30 | included in a sub-node named 'regulators'. Regulator nodes included in this | ||
31 | sub-node should be of the format as listed below. | ||
32 | |||
33 | regulator_name { | ||
34 | standard regulator bindings here | ||
35 | }; | ||
36 | |||
37 | Example: | ||
38 | max17135@48 { | ||
39 | compatible = "maxim,max17135"; | ||
40 | reg = <0x48>; | ||
41 | vneg_pwrup = <1>; | ||
42 | gvee_pwrup = <1>; | ||
43 | vpos_pwrup = <2>; | ||
44 | gvdd_pwrup = <1>; | ||
45 | gvdd_pwrdn = <1>; | ||
46 | vpos_pwrdn = <2>; | ||
47 | gvee_pwrdn = <1>; | ||
48 | vneg_pwrdn = <1>; | ||
49 | SENSOR-supply = <®_sensor>; | ||
50 | gpio_pmic_pwrgood = <&gpio2 21 0>; | ||
51 | gpio_pmic_vcom_ctrl = <&gpio3 17 0>; | ||
52 | gpio_pmic_wakeup = <&gpio3 20 0>; | ||
53 | gpio_pmic_v3p3 = <&gpio2 20 0>; | ||
54 | gpio_pmic_intr = <&gpio2 25 0>; | ||
55 | |||
56 | regulators { | ||
57 | DISPLAY_reg: DISPLAY { | ||
58 | regulator-name = "DISPLAY"; | ||
59 | }; | ||
60 | |||
61 | GVDD_reg: GVDD { | ||
62 | regulator-name = "GVDD"; | ||
63 | regulator-min-microvolt = <20000000>; | ||
64 | regulator-max-microvolt = <20000000>; | ||
65 | }; | ||
66 | |||
67 | GVEE_reg: GVEE { | ||
68 | regulator-name = "GVEE"; | ||
69 | /* 2's-compliment, -22000000 */ | ||
70 | regulator-min-microvolt = <0xfeb04e80>; | ||
71 | regulator-max-microvolt = <0xfeb04e80>; | ||
72 | }; | ||
73 | |||
74 | HVINN_reg: HVINN { | ||
75 | regulator-name = "HVINN"; | ||
76 | /* 2's-compliment, -22000000 */ | ||
77 | regulator-min-microvolt = <0xfeb04e80>; | ||
78 | regulator-max-microvolt = <0xfeb04e80>; | ||
79 | }; | ||
80 | |||
81 | HVINP_reg: HVINP { | ||
82 | regulator-name = "HVINP"; | ||
83 | regulator-min-microvolt = <20000000>; | ||
84 | regulator-max-microvolt = <20000000>; | ||
85 | }; | ||
86 | |||
87 | VCOM_reg: VCOM { | ||
88 | regulator-name = "VCOM"; | ||
89 | /* 2's-compliment, -4325000 */ | ||
90 | regulator-min-microvolt = <0xffbe0178>; | ||
91 | /* 2's-compliment, -500000 */ | ||
92 | regulator-max-microvolt = <0xfff85ee0>; | ||
93 | }; | ||
94 | |||
95 | VNEG_reg: VNEG { | ||
96 | regulator-name = "VNEG"; | ||
97 | /* 2's-compliment, -15000000 */ | ||
98 | regulator-min-microvolt = <0xff1b1e40>; | ||
99 | regulator-max-microvolt = <0xff1b1e40>; | ||
100 | }; | ||
101 | |||
102 | VPOS_reg: VPOS { | ||
103 | regulator-name = "VPOS"; | ||
104 | regulator-min-microvolt = <15000000>; | ||
105 | regulator-max-microvolt = <15000000>; | ||
106 | }; | ||
107 | |||
108 | V3P3_reg: V3P3 { | ||
109 | regulator-name = "V3P3"; | ||
110 | }; | ||
111 | }; | ||
112 | }; | ||
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index cac5aaa90a01..981a22f0812e 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -867,6 +867,15 @@ config SENSORS_MAX1668 | |||
867 | This driver can also be built as a module. If so, the module | 867 | This driver can also be built as a module. If so, the module |
868 | will be called max1668. | 868 | will be called max1668. |
869 | 869 | ||
870 | config SENSORS_MAX17135 | ||
871 | tristate "Maxim MAX17135 EPD temperature sensor" | ||
872 | depends on I2C | ||
873 | help | ||
874 | If you say yes here you get support for MAX17135 PMIC sensor. | ||
875 | |||
876 | This driver can also be built as a module. If so, the module | ||
877 | will be called max17135_sensor. | ||
878 | |||
870 | config SENSORS_MAX197 | 879 | config SENSORS_MAX197 |
871 | tristate "Maxim MAX197 and compatibles" | 880 | tristate "Maxim MAX197 and compatibles" |
872 | help | 881 | help |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 8f30a685567b..43fe743901ee 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
@@ -101,6 +101,7 @@ obj-$(CONFIG_SENSORS_MAX1111) += max1111.o | |||
101 | obj-$(CONFIG_SENSORS_MAX16065) += max16065.o | 101 | obj-$(CONFIG_SENSORS_MAX16065) += max16065.o |
102 | obj-$(CONFIG_SENSORS_MAX1619) += max1619.o | 102 | obj-$(CONFIG_SENSORS_MAX1619) += max1619.o |
103 | obj-$(CONFIG_SENSORS_MAX1668) += max1668.o | 103 | obj-$(CONFIG_SENSORS_MAX1668) += max1668.o |
104 | obj-$(CONFIG_SENSORS_MAX17135) += max17135-hwmon.o | ||
104 | obj-$(CONFIG_SENSORS_MAX197) += max197.o | 105 | obj-$(CONFIG_SENSORS_MAX197) += max197.o |
105 | obj-$(CONFIG_SENSORS_MAX6639) += max6639.o | 106 | obj-$(CONFIG_SENSORS_MAX6639) += max6639.o |
106 | obj-$(CONFIG_SENSORS_MAX6642) += max6642.o | 107 | obj-$(CONFIG_SENSORS_MAX6642) += max6642.o |
diff --git a/drivers/hwmon/max17135-hwmon.c b/drivers/hwmon/max17135-hwmon.c new file mode 100644 index 000000000000..8e92268a91ab --- /dev/null +++ b/drivers/hwmon/max17135-hwmon.c | |||
@@ -0,0 +1,176 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
17 | * | ||
18 | */ | ||
19 | /* | ||
20 | * max17135.c | ||
21 | * | ||
22 | * Based on the MAX1619 driver. | ||
23 | * Copyright (C) 2003-2004 Alexey Fisher <fishor@mail.ru> | ||
24 | * Jean Delvare <khali@linux-fr.org> | ||
25 | * | ||
26 | * The MAX17135 is a sensor chip made by Maxim. | ||
27 | * It reports up to two temperatures (its own plus up to | ||
28 | * one external one). | ||
29 | */ | ||
30 | |||
31 | |||
32 | #include <linux/module.h> | ||
33 | #include <linux/init.h> | ||
34 | #include <linux/slab.h> | ||
35 | #include <linux/jiffies.h> | ||
36 | #include <linux/hwmon.h> | ||
37 | #include <linux/hwmon-sysfs.h> | ||
38 | #include <linux/err.h> | ||
39 | #include <linux/sysfs.h> | ||
40 | #include <linux/platform_device.h> | ||
41 | #include <linux/mfd/max17135.h> | ||
42 | |||
43 | /* | ||
44 | * Conversions | ||
45 | */ | ||
46 | static int temp_from_reg(int val) | ||
47 | { | ||
48 | return val >> 8; | ||
49 | } | ||
50 | |||
51 | /* | ||
52 | * Functions declaration | ||
53 | */ | ||
54 | static int max17135_sensor_probe(struct platform_device *pdev); | ||
55 | static int max17135_sensor_remove(struct platform_device *pdev); | ||
56 | |||
57 | static const struct platform_device_id max17135_sns_id[] = { | ||
58 | { "max17135-sns", 0}, | ||
59 | { /* sentinel */ }, | ||
60 | }; | ||
61 | MODULE_DEVICE_TABLE(platform, max17135_sns_id); | ||
62 | |||
63 | /* | ||
64 | * Driver data (common to all clients) | ||
65 | */ | ||
66 | static struct platform_driver max17135_sensor_driver = { | ||
67 | .probe = max17135_sensor_probe, | ||
68 | .remove = max17135_sensor_remove, | ||
69 | .id_table = max17135_sns_id, | ||
70 | .driver = { | ||
71 | .name = "max17135_sensor", | ||
72 | }, | ||
73 | }; | ||
74 | |||
75 | /* | ||
76 | * Client data (each client gets its own) | ||
77 | */ | ||
78 | struct max17135_data { | ||
79 | struct device *hwmon_dev; | ||
80 | }; | ||
81 | |||
82 | /* | ||
83 | * Sysfs stuff | ||
84 | */ | ||
85 | static ssize_t show_temp_input1(struct device *dev, | ||
86 | struct device_attribute *attr, char *buf) | ||
87 | { | ||
88 | unsigned int reg_val; | ||
89 | max17135_reg_read(REG_MAX17135_INT_TEMP, ®_val); | ||
90 | return snprintf(buf, PAGE_SIZE, "%d\n", temp_from_reg(reg_val)); | ||
91 | } | ||
92 | |||
93 | static ssize_t show_temp_input2(struct device *dev, | ||
94 | struct device_attribute *attr, char *buf) | ||
95 | { | ||
96 | unsigned int reg_val; | ||
97 | max17135_reg_read(REG_MAX17135_EXT_TEMP, ®_val); | ||
98 | return snprintf(buf, PAGE_SIZE, "%d\n", temp_from_reg(reg_val)); | ||
99 | } | ||
100 | |||
101 | static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input1, NULL); | ||
102 | static DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_input2, NULL); | ||
103 | |||
104 | static struct attribute *max17135_attributes[] = { | ||
105 | &dev_attr_temp1_input.attr, | ||
106 | &dev_attr_temp2_input.attr, | ||
107 | NULL | ||
108 | }; | ||
109 | |||
110 | static const struct attribute_group max17135_group = { | ||
111 | .attrs = max17135_attributes, | ||
112 | }; | ||
113 | |||
114 | /* | ||
115 | * Real code | ||
116 | */ | ||
117 | static int max17135_sensor_probe(struct platform_device *pdev) | ||
118 | { | ||
119 | struct max17135_data *data; | ||
120 | int err; | ||
121 | |||
122 | data = kzalloc(sizeof(struct max17135_data), GFP_KERNEL); | ||
123 | if (!data) { | ||
124 | err = -ENOMEM; | ||
125 | goto exit; | ||
126 | } | ||
127 | |||
128 | /* Register sysfs hooks */ | ||
129 | err = sysfs_create_group(&pdev->dev.kobj, &max17135_group); | ||
130 | if (err) | ||
131 | goto exit_free; | ||
132 | |||
133 | data->hwmon_dev = hwmon_device_register(&pdev->dev); | ||
134 | if (IS_ERR(data->hwmon_dev)) { | ||
135 | err = PTR_ERR(data->hwmon_dev); | ||
136 | goto exit_remove_files; | ||
137 | } | ||
138 | |||
139 | platform_set_drvdata(pdev, data); | ||
140 | |||
141 | return 0; | ||
142 | |||
143 | exit_remove_files: | ||
144 | sysfs_remove_group(&pdev->dev.kobj, &max17135_group); | ||
145 | exit_free: | ||
146 | kfree(data); | ||
147 | exit: | ||
148 | return err; | ||
149 | } | ||
150 | |||
151 | static int max17135_sensor_remove(struct platform_device *pdev) | ||
152 | { | ||
153 | struct max17135_data *data = platform_get_drvdata(pdev); | ||
154 | |||
155 | hwmon_device_unregister(data->hwmon_dev); | ||
156 | sysfs_remove_group(&pdev->dev.kobj, &max17135_group); | ||
157 | |||
158 | kfree(data); | ||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | static int __init sensors_max17135_init(void) | ||
163 | { | ||
164 | return platform_driver_register(&max17135_sensor_driver); | ||
165 | } | ||
166 | module_init(sensors_max17135_init); | ||
167 | |||
168 | static void __exit sensors_max17135_exit(void) | ||
169 | { | ||
170 | platform_driver_unregister(&max17135_sensor_driver); | ||
171 | } | ||
172 | module_exit(sensors_max17135_exit); | ||
173 | |||
174 | MODULE_DESCRIPTION("MAX17135 sensor driver"); | ||
175 | MODULE_LICENSE("GPL"); | ||
176 | |||
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 2cca35ac5209..3e894e84a46c 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig | |||
@@ -284,6 +284,13 @@ config MFD_88PM860X | |||
284 | select individual components like voltage regulators, RTC and | 284 | select individual components like voltage regulators, RTC and |
285 | battery-charger under the corresponding menus. | 285 | battery-charger under the corresponding menus. |
286 | 286 | ||
287 | config MFD_MAX17135 | ||
288 | tristate "Maxim MAX17135 EPD PMIC core" | ||
289 | depends on I2C | ||
290 | help | ||
291 | This is the MAX17135 PMIC support. It includes | ||
292 | core support for communication with the MAX17135 chip. | ||
293 | |||
287 | config MFD_MAX77686 | 294 | config MFD_MAX77686 |
288 | bool "Maxim Semiconductor MAX77686 PMIC Support" | 295 | bool "Maxim Semiconductor MAX77686 PMIC Support" |
289 | depends on I2C=y && GENERIC_HARDIRQS | 296 | depends on I2C=y && GENERIC_HARDIRQS |
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 41ab2b45e188..8e8ebf35885b 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile | |||
@@ -104,6 +104,7 @@ obj-$(CONFIG_MFD_LP8788) += lp8788.o lp8788-irq.o | |||
104 | da9055-objs := da9055-core.o da9055-i2c.o | 104 | da9055-objs := da9055-core.o da9055-i2c.o |
105 | obj-$(CONFIG_MFD_DA9055) += da9055.o | 105 | obj-$(CONFIG_MFD_DA9055) += da9055.o |
106 | 106 | ||
107 | obj-$(CONFIG_MFD_MAX17135) += max17135-core.o | ||
107 | obj-$(CONFIG_MFD_MAX77686) += max77686.o max77686-irq.o | 108 | obj-$(CONFIG_MFD_MAX77686) += max77686.o max77686-irq.o |
108 | obj-$(CONFIG_MFD_MAX77693) += max77693.o max77693-irq.o | 109 | obj-$(CONFIG_MFD_MAX77693) += max77693.o max77693-irq.o |
109 | obj-$(CONFIG_MFD_MAX8907) += max8907.o | 110 | obj-$(CONFIG_MFD_MAX8907) += max8907.o |
diff --git a/drivers/mfd/max17135-core.c b/drivers/mfd/max17135-core.c new file mode 100644 index 000000000000..caef5ceadb5c --- /dev/null +++ b/drivers/mfd/max17135-core.c | |||
@@ -0,0 +1,295 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
17 | * | ||
18 | */ | ||
19 | |||
20 | /*! | ||
21 | * @file pmic/core/max17135.c | ||
22 | * @brief This file contains MAX17135 specific PMIC code. This implementaion | ||
23 | * may differ for each PMIC chip. | ||
24 | * | ||
25 | * @ingroup PMIC_CORE | ||
26 | */ | ||
27 | |||
28 | /* | ||
29 | * Includes | ||
30 | */ | ||
31 | #include <linux/kernel.h> | ||
32 | #include <linux/module.h> | ||
33 | #include <linux/init.h> | ||
34 | #include <linux/slab.h> | ||
35 | #include <linux/device.h> | ||
36 | #include <linux/i2c.h> | ||
37 | #include <linux/delay.h> | ||
38 | #include <linux/err.h> | ||
39 | #include <linux/uaccess.h> | ||
40 | #include <linux/of.h> | ||
41 | #include <linux/of_device.h> | ||
42 | #include <linux/of_gpio.h> | ||
43 | #include <linux/platform_device.h> | ||
44 | #include <linux/regulator/machine.h> | ||
45 | #include <linux/pmic_status.h> | ||
46 | #include <linux/mfd/core.h> | ||
47 | #include <linux/mfd/max17135.h> | ||
48 | #include <asm/mach-types.h> | ||
49 | |||
50 | static int max17135_detect(struct i2c_client *client, | ||
51 | struct i2c_board_info *info); | ||
52 | struct i2c_client *max17135_client; | ||
53 | static struct regulator *gpio_regulator; | ||
54 | |||
55 | static struct mfd_cell max17135_devs[] = { | ||
56 | { .name = "max17135-pmic", }, | ||
57 | { .name = "max17135-sns", }, | ||
58 | }; | ||
59 | |||
60 | static const unsigned short normal_i2c[] = {0x48, I2C_CLIENT_END}; | ||
61 | |||
62 | int max17135_reg_read(int reg_num, unsigned int *reg_val) | ||
63 | { | ||
64 | int result; | ||
65 | |||
66 | if (max17135_client == NULL) | ||
67 | return PMIC_ERROR; | ||
68 | |||
69 | if ((reg_num == REG_MAX17135_EXT_TEMP) || | ||
70 | (reg_num == REG_MAX17135_INT_TEMP)) { | ||
71 | result = i2c_smbus_read_word_data(max17135_client, reg_num); | ||
72 | if (result < 0) { | ||
73 | dev_err(&max17135_client->dev, | ||
74 | "Unable to read MAX17135 register via I2C\n"); | ||
75 | return PMIC_ERROR; | ||
76 | } | ||
77 | /* Swap bytes for dword read */ | ||
78 | result = (result >> 8) | ((result & 0xFF) << 8); | ||
79 | } else { | ||
80 | result = i2c_smbus_read_byte_data(max17135_client, reg_num); | ||
81 | if (result < 0) { | ||
82 | dev_err(&max17135_client->dev, | ||
83 | "Unable to read MAX17135 register via I2C\n"); | ||
84 | return PMIC_ERROR; | ||
85 | } | ||
86 | } | ||
87 | |||
88 | *reg_val = result; | ||
89 | return PMIC_SUCCESS; | ||
90 | } | ||
91 | |||
92 | int max17135_reg_write(int reg_num, const unsigned int reg_val) | ||
93 | { | ||
94 | int result; | ||
95 | |||
96 | if (max17135_client == NULL) | ||
97 | return PMIC_ERROR; | ||
98 | |||
99 | result = i2c_smbus_write_byte_data(max17135_client, reg_num, reg_val); | ||
100 | if (result < 0) { | ||
101 | dev_err(&max17135_client->dev, | ||
102 | "Unable to write MAX17135 register via I2C\n"); | ||
103 | return PMIC_ERROR; | ||
104 | } | ||
105 | |||
106 | return PMIC_SUCCESS; | ||
107 | } | ||
108 | |||
109 | #ifdef CONFIG_OF | ||
110 | static struct max17135_platform_data *max17135_i2c_parse_dt_pdata( | ||
111 | struct device *dev) | ||
112 | { | ||
113 | struct max17135_platform_data *pdata; | ||
114 | |||
115 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | ||
116 | if (!pdata) { | ||
117 | dev_err(dev, "could not allocate memory for pdata\n"); | ||
118 | return ERR_PTR(-ENOMEM); | ||
119 | } | ||
120 | |||
121 | return pdata; | ||
122 | } | ||
123 | #else | ||
124 | static struct max17135_platform_data *max17135_i2c_parse_dt_pdata( | ||
125 | struct device *dev) | ||
126 | { | ||
127 | return NULL; | ||
128 | } | ||
129 | #endif /* !CONFIG_OF */ | ||
130 | |||
131 | static int max17135_probe(struct i2c_client *client, | ||
132 | const struct i2c_device_id *id) | ||
133 | { | ||
134 | struct max17135 *max17135; | ||
135 | struct max17135_platform_data *pdata = client->dev.platform_data; | ||
136 | struct device_node *np = client->dev.of_node; | ||
137 | int ret = 0; | ||
138 | |||
139 | if (!np) | ||
140 | return -ENODEV; | ||
141 | |||
142 | gpio_regulator = devm_regulator_get(&client->dev, "SENSOR"); | ||
143 | if (!IS_ERR(gpio_regulator)) { | ||
144 | ret = regulator_enable(gpio_regulator); | ||
145 | if (ret) { | ||
146 | dev_err(&client->dev, "gpio set voltage error\n"); | ||
147 | return ret; | ||
148 | } | ||
149 | } | ||
150 | |||
151 | /* Create the PMIC data structure */ | ||
152 | max17135 = kzalloc(sizeof(struct max17135), GFP_KERNEL); | ||
153 | if (max17135 == NULL) { | ||
154 | kfree(client); | ||
155 | return -ENOMEM; | ||
156 | } | ||
157 | |||
158 | /* Initialize the PMIC data structure */ | ||
159 | i2c_set_clientdata(client, max17135); | ||
160 | max17135->dev = &client->dev; | ||
161 | max17135->i2c_client = client; | ||
162 | |||
163 | max17135_client = client; | ||
164 | ret = max17135_detect(client, NULL); | ||
165 | if (ret) | ||
166 | goto err1; | ||
167 | |||
168 | mfd_add_devices(max17135->dev, -1, max17135_devs, | ||
169 | ARRAY_SIZE(max17135_devs), | ||
170 | NULL, 0, NULL); | ||
171 | |||
172 | if (max17135->dev->of_node) { | ||
173 | pdata = max17135_i2c_parse_dt_pdata(max17135->dev); | ||
174 | if (IS_ERR(pdata)) { | ||
175 | ret = PTR_ERR(pdata); | ||
176 | goto err2; | ||
177 | } | ||
178 | |||
179 | } | ||
180 | max17135->pdata = pdata; | ||
181 | |||
182 | dev_info(&client->dev, "PMIC MAX17135 for eInk display\n"); | ||
183 | |||
184 | return ret; | ||
185 | err2: | ||
186 | mfd_remove_devices(max17135->dev); | ||
187 | err1: | ||
188 | kfree(max17135); | ||
189 | |||
190 | return ret; | ||
191 | } | ||
192 | |||
193 | |||
194 | static int max17135_remove(struct i2c_client *i2c) | ||
195 | { | ||
196 | struct max17135 *max17135 = i2c_get_clientdata(i2c); | ||
197 | |||
198 | mfd_remove_devices(max17135->dev); | ||
199 | return 0; | ||
200 | } | ||
201 | |||
202 | static int max17135_suspend(struct i2c_client *client, pm_message_t state) | ||
203 | { | ||
204 | return 0; | ||
205 | } | ||
206 | |||
207 | static int max17135_resume(struct i2c_client *client) | ||
208 | { | ||
209 | return 0; | ||
210 | } | ||
211 | |||
212 | /* Return 0 if detection is successful, -ENODEV otherwise */ | ||
213 | static int max17135_detect(struct i2c_client *client, | ||
214 | struct i2c_board_info *info) | ||
215 | { | ||
216 | struct i2c_adapter *adapter = client->adapter; | ||
217 | u8 chip_rev, chip_id; | ||
218 | |||
219 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
220 | return -ENODEV; | ||
221 | |||
222 | /* detection */ | ||
223 | if (i2c_smbus_read_byte_data(client, | ||
224 | REG_MAX17135_PRODUCT_REV) != 0) { | ||
225 | dev_err(&adapter->dev, | ||
226 | "Max17135 PMIC not found!\n"); | ||
227 | return -ENODEV; | ||
228 | } | ||
229 | |||
230 | /* identification */ | ||
231 | chip_rev = i2c_smbus_read_byte_data(client, | ||
232 | REG_MAX17135_PRODUCT_REV); | ||
233 | chip_id = i2c_smbus_read_byte_data(client, | ||
234 | REG_MAX17135_PRODUCT_ID); | ||
235 | |||
236 | if (chip_rev != 0x00 || chip_id != 0x4D) { /* identification failed */ | ||
237 | dev_info(&adapter->dev, | ||
238 | "Unsupported chip (man_id=0x%02X, " | ||
239 | "chip_id=0x%02X).\n", chip_rev, chip_id); | ||
240 | return -ENODEV; | ||
241 | } | ||
242 | |||
243 | if (info) | ||
244 | strlcpy(info->type, "max17135_sensor", I2C_NAME_SIZE); | ||
245 | |||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | static const struct i2c_device_id max17135_id[] = { | ||
250 | { "max17135", 0 }, | ||
251 | { } | ||
252 | }; | ||
253 | MODULE_DEVICE_TABLE(i2c, max17135_id); | ||
254 | |||
255 | static const struct of_device_id max17135_dt_ids[] = { | ||
256 | { | ||
257 | .compatible = "maxim,max17135", | ||
258 | .data = (void *) &max17135_id[0], | ||
259 | }, { | ||
260 | /* sentinel */ | ||
261 | } | ||
262 | }; | ||
263 | MODULE_DEVICE_TABLE(of, max17135_dt_ids); | ||
264 | |||
265 | |||
266 | static struct i2c_driver max17135_driver = { | ||
267 | .driver = { | ||
268 | .name = "max17135", | ||
269 | .owner = THIS_MODULE, | ||
270 | .of_match_table = max17135_dt_ids, | ||
271 | }, | ||
272 | .probe = max17135_probe, | ||
273 | .remove = max17135_remove, | ||
274 | .suspend = max17135_suspend, | ||
275 | .resume = max17135_resume, | ||
276 | .id_table = max17135_id, | ||
277 | .detect = max17135_detect, | ||
278 | .address_list = &normal_i2c[0], | ||
279 | }; | ||
280 | |||
281 | static int __init max17135_init(void) | ||
282 | { | ||
283 | return i2c_add_driver(&max17135_driver); | ||
284 | } | ||
285 | |||
286 | static void __exit max17135_exit(void) | ||
287 | { | ||
288 | i2c_del_driver(&max17135_driver); | ||
289 | } | ||
290 | |||
291 | /* | ||
292 | * Module entry points | ||
293 | */ | ||
294 | subsys_initcall(max17135_init); | ||
295 | module_exit(max17135_exit); | ||
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 220612b1c4d1..133940473de4 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig | |||
@@ -178,6 +178,10 @@ config REGULATOR_MAX1586 | |||
178 | regulator via I2C bus. The provided regulator is suitable | 178 | regulator via I2C bus. The provided regulator is suitable |
179 | for PXA27x chips to control VCC_CORE and VCC_USIM voltages. | 179 | for PXA27x chips to control VCC_CORE and VCC_USIM voltages. |
180 | 180 | ||
181 | config REGULATOR_MAX17135 | ||
182 | tristate "Maxim MAX17135 Regulator Support" | ||
183 | depends on MFD_MAX17135 | ||
184 | |||
181 | config REGULATOR_MAX8649 | 185 | config REGULATOR_MAX8649 |
182 | tristate "Maxim 8649 voltage regulator" | 186 | tristate "Maxim 8649 voltage regulator" |
183 | depends on I2C | 187 | depends on I2C |
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 1375759189b1..5234d8767fb2 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile | |||
@@ -32,6 +32,7 @@ obj-$(CONFIG_REGULATOR_LP8788) += lp8788-buck.o | |||
32 | obj-$(CONFIG_REGULATOR_LP8788) += lp8788-ldo.o | 32 | obj-$(CONFIG_REGULATOR_LP8788) += lp8788-ldo.o |
33 | obj-$(CONFIG_REGULATOR_LP8755) += lp8755.o | 33 | obj-$(CONFIG_REGULATOR_LP8755) += lp8755.o |
34 | obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o | 34 | obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o |
35 | obj-$(CONFIG_REGULATOR_MAX17135) += max17135-regulator.o | ||
35 | obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o | 36 | obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o |
36 | obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o | 37 | obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o |
37 | obj-$(CONFIG_REGULATOR_MAX8907) += max8907-regulator.o | 38 | obj-$(CONFIG_REGULATOR_MAX8907) += max8907-regulator.o |
diff --git a/drivers/regulator/max17135-regulator.c b/drivers/regulator/max17135-regulator.c new file mode 100644 index 000000000000..3b3d71b4d6bf --- /dev/null +++ b/drivers/regulator/max17135-regulator.c | |||
@@ -0,0 +1,838 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | |||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | |||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
17 | */ | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/i2c.h> | ||
23 | #include <linux/mutex.h> | ||
24 | #include <linux/delay.h> | ||
25 | #include <linux/err.h> | ||
26 | #include <linux/platform_device.h> | ||
27 | #include <linux/regulator/machine.h> | ||
28 | #include <linux/regulator/driver.h> | ||
29 | #include <linux/regulator/of_regulator.h> | ||
30 | #include <linux/mfd/max17135.h> | ||
31 | #include <linux/gpio.h> | ||
32 | #include <linux/of_gpio.h> | ||
33 | |||
34 | /* | ||
35 | * Regulator definitions | ||
36 | * *_MIN_uV - minimum microvolt for regulator | ||
37 | * *_MAX_uV - maximum microvolt for regulator | ||
38 | * *_STEP_uV - microvolts between regulator output levels | ||
39 | * *_MIN_VAL - minimum register field value for regulator | ||
40 | * *_MAX_VAL - maximum register field value for regulator | ||
41 | */ | ||
42 | #define MAX17135_HVINP_MIN_uV 5000000 | ||
43 | #define MAX17135_HVINP_MAX_uV 20000000 | ||
44 | #define MAX17135_HVINP_STEP_uV 1000000 | ||
45 | #define MAX17135_HVINP_MIN_VAL 0 | ||
46 | #define MAX17135_HVINP_MAX_VAL 1 | ||
47 | |||
48 | #define MAX17135_HVINN_MIN_uV 5000000 | ||
49 | #define MAX17135_HVINN_MAX_uV 20000000 | ||
50 | #define MAX17135_HVINN_STEP_uV 1000000 | ||
51 | #define MAX17135_HVINN_MIN_VAL 0 | ||
52 | #define MAX17135_HVINN_MAX_VAL 1 | ||
53 | |||
54 | #define MAX17135_GVDD_MIN_uV 5000000 | ||
55 | #define MAX17135_GVDD_MAX_uV 20000000 | ||
56 | #define MAX17135_GVDD_STEP_uV 1000000 | ||
57 | #define MAX17135_GVDD_MIN_VAL 0 | ||
58 | #define MAX17135_GVDD_MAX_VAL 1 | ||
59 | |||
60 | #define MAX17135_GVEE_MIN_uV 5000000 | ||
61 | #define MAX17135_GVEE_MAX_uV 20000000 | ||
62 | #define MAX17135_GVEE_STEP_uV 1000000 | ||
63 | #define MAX17135_GVEE_MIN_VAL 0 | ||
64 | #define MAX17135_GVEE_MAX_VAL 1 | ||
65 | |||
66 | #define MAX17135_VCOM_MIN_VAL 0 | ||
67 | #define MAX17135_VCOM_MAX_VAL 255 | ||
68 | |||
69 | #define MAX17135_VNEG_MIN_uV 5000000 | ||
70 | #define MAX17135_VNEG_MAX_uV 20000000 | ||
71 | #define MAX17135_VNEG_STEP_uV 1000000 | ||
72 | #define MAX17135_VNEG_MIN_VAL 0 | ||
73 | #define MAX17135_VNEG_MAX_VAL 1 | ||
74 | |||
75 | #define MAX17135_VPOS_MIN_uV 5000000 | ||
76 | #define MAX17135_VPOS_MAX_uV 20000000 | ||
77 | #define MAX17135_VPOS_STEP_uV 1000000 | ||
78 | #define MAX17135_VPOS_MIN_VAL 0 | ||
79 | #define MAX17135_VPOS_MAX_VAL 1 | ||
80 | |||
81 | struct max17135_vcom_programming_data { | ||
82 | int vcom_min_uV; | ||
83 | int vcom_max_uV; | ||
84 | int vcom_step_uV; | ||
85 | }; | ||
86 | |||
87 | struct max17135_data { | ||
88 | int num_regulators; | ||
89 | struct max17135 *max17135; | ||
90 | struct regulator_dev **rdev; | ||
91 | }; | ||
92 | |||
93 | static long unsigned int max17135_pass_num = { 1 }; | ||
94 | static int max17135_vcom = { -1250000 }; | ||
95 | |||
96 | struct max17135_vcom_programming_data vcom_data[2] = { | ||
97 | { | ||
98 | -4325000, | ||
99 | -500000, | ||
100 | 15000, | ||
101 | }, | ||
102 | { | ||
103 | -3050000, | ||
104 | -500000, | ||
105 | 10000, | ||
106 | }, | ||
107 | }; | ||
108 | |||
109 | static int max17135_is_power_good(struct max17135 *max17135); | ||
110 | |||
111 | /* | ||
112 | * Regulator operations | ||
113 | */ | ||
114 | static int max17135_hvinp_set_voltage(struct regulator_dev *reg, | ||
115 | int minuV, int uV, unsigned *selector) | ||
116 | { | ||
117 | unsigned int reg_val; | ||
118 | unsigned int fld_val; | ||
119 | |||
120 | if ((uV >= MAX17135_HVINP_MIN_uV) && | ||
121 | (uV <= MAX17135_HVINP_MAX_uV)) | ||
122 | fld_val = (uV - MAX17135_HVINP_MIN_uV) / | ||
123 | MAX17135_HVINP_STEP_uV; | ||
124 | else | ||
125 | return -EINVAL; | ||
126 | |||
127 | max17135_reg_read(REG_MAX17135_HVINP, ®_val); | ||
128 | |||
129 | reg_val &= ~BITFMASK(HVINP); | ||
130 | reg_val |= BITFVAL(HVINP, fld_val); /* shift to correct bit */ | ||
131 | |||
132 | return max17135_reg_write(REG_MAX17135_HVINP, reg_val); | ||
133 | } | ||
134 | |||
135 | static int max17135_hvinp_get_voltage(struct regulator_dev *reg) | ||
136 | { | ||
137 | unsigned int reg_val; | ||
138 | unsigned int fld_val; | ||
139 | int volt; | ||
140 | |||
141 | max17135_reg_read(REG_MAX17135_HVINP, ®_val); | ||
142 | |||
143 | fld_val = (reg_val & BITFMASK(HVINP)) >> HVINP_LSH; | ||
144 | |||
145 | if ((fld_val >= MAX17135_HVINP_MIN_VAL) && | ||
146 | (fld_val <= MAX17135_HVINP_MAX_VAL)) { | ||
147 | volt = (fld_val * MAX17135_HVINP_STEP_uV) + | ||
148 | MAX17135_HVINP_MIN_uV; | ||
149 | } else { | ||
150 | printk(KERN_ERR "MAX17135: HVINP voltage is out of range\n"); | ||
151 | volt = 0; | ||
152 | } | ||
153 | return volt; | ||
154 | } | ||
155 | |||
156 | static int max17135_hvinp_enable(struct regulator_dev *reg) | ||
157 | { | ||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | static int max17135_hvinp_disable(struct regulator_dev *reg) | ||
162 | { | ||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | /* Convert uV to the VCOM register bitfield setting */ | ||
167 | static inline int vcom_uV_to_rs(int uV, int pass_num) | ||
168 | { | ||
169 | return (vcom_data[pass_num].vcom_max_uV - uV) | ||
170 | / vcom_data[pass_num].vcom_step_uV; | ||
171 | } | ||
172 | |||
173 | /* Convert the VCOM register bitfield setting to uV */ | ||
174 | static inline int vcom_rs_to_uV(int rs, int pass_num) | ||
175 | { | ||
176 | return vcom_data[pass_num].vcom_max_uV | ||
177 | - (vcom_data[pass_num].vcom_step_uV * rs); | ||
178 | } | ||
179 | |||
180 | static int max17135_vcom_set_voltage(struct regulator_dev *reg, | ||
181 | int minuV, int uV, unsigned *selector) | ||
182 | { | ||
183 | struct max17135 *max17135 = rdev_get_drvdata(reg); | ||
184 | unsigned int reg_val; | ||
185 | int vcom_read; | ||
186 | |||
187 | if ((uV < vcom_data[max17135->pass_num-1].vcom_min_uV) | ||
188 | || (uV > vcom_data[max17135->pass_num-1].vcom_max_uV)) | ||
189 | return -EINVAL; | ||
190 | |||
191 | max17135_reg_read(REG_MAX17135_DVR, ®_val); | ||
192 | |||
193 | /* | ||
194 | * Only program VCOM if it is not set to the desired value. | ||
195 | * Programming VCOM excessively degrades ability to keep | ||
196 | * DVR register value persistent. | ||
197 | */ | ||
198 | vcom_read = vcom_rs_to_uV(reg_val, max17135->pass_num-1); | ||
199 | if (vcom_read != max17135->vcom_uV) { | ||
200 | reg_val &= ~BITFMASK(DVR); | ||
201 | reg_val |= BITFVAL(DVR, vcom_uV_to_rs(uV, | ||
202 | max17135->pass_num-1)); | ||
203 | max17135_reg_write(REG_MAX17135_DVR, reg_val); | ||
204 | |||
205 | reg_val = BITFVAL(CTRL_DVR, true); /* shift to correct bit */ | ||
206 | return max17135_reg_write(REG_MAX17135_PRGM_CTRL, reg_val); | ||
207 | } | ||
208 | |||
209 | return 0; | ||
210 | } | ||
211 | |||
212 | static int max17135_vcom_get_voltage(struct regulator_dev *reg) | ||
213 | { | ||
214 | struct max17135 *max17135 = rdev_get_drvdata(reg); | ||
215 | unsigned int reg_val; | ||
216 | |||
217 | max17135_reg_read(REG_MAX17135_DVR, ®_val); | ||
218 | return vcom_rs_to_uV(BITFEXT(reg_val, DVR), max17135->pass_num-1); | ||
219 | } | ||
220 | |||
221 | static int max17135_vcom_enable(struct regulator_dev *reg) | ||
222 | { | ||
223 | struct max17135 *max17135 = rdev_get_drvdata(reg); | ||
224 | |||
225 | /* | ||
226 | * Check to see if we need to set the VCOM voltage. | ||
227 | * Should only be done one time. And, we can | ||
228 | * only change vcom voltage if we have been enabled. | ||
229 | */ | ||
230 | if (!max17135->vcom_setup && max17135_is_power_good(max17135)) { | ||
231 | max17135_vcom_set_voltage(reg, | ||
232 | max17135->vcom_uV, | ||
233 | max17135->vcom_uV, | ||
234 | NULL); | ||
235 | max17135->vcom_setup = true; | ||
236 | } | ||
237 | |||
238 | /* enable VCOM regulator output */ | ||
239 | if (max17135->pass_num == 1) | ||
240 | gpio_set_value(max17135->gpio_pmic_vcom_ctrl, 1); | ||
241 | else { | ||
242 | unsigned int reg_val; | ||
243 | |||
244 | max17135_reg_read(REG_MAX17135_ENABLE, ®_val); | ||
245 | reg_val &= ~BITFMASK(VCOM_ENABLE); | ||
246 | reg_val |= BITFVAL(VCOM_ENABLE, 1); /* shift to correct bit */ | ||
247 | max17135_reg_write(REG_MAX17135_ENABLE, reg_val); | ||
248 | } | ||
249 | |||
250 | return 0; | ||
251 | } | ||
252 | |||
253 | static int max17135_vcom_disable(struct regulator_dev *reg) | ||
254 | { | ||
255 | struct max17135 *max17135 = rdev_get_drvdata(reg); | ||
256 | |||
257 | if (max17135->pass_num == 1) | ||
258 | gpio_set_value(max17135->gpio_pmic_vcom_ctrl, 0); | ||
259 | else { | ||
260 | unsigned int reg_val; | ||
261 | |||
262 | max17135_reg_read(REG_MAX17135_ENABLE, ®_val); | ||
263 | reg_val &= ~BITFMASK(VCOM_ENABLE); | ||
264 | max17135_reg_write(REG_MAX17135_ENABLE, reg_val); | ||
265 | } | ||
266 | |||
267 | return 0; | ||
268 | } | ||
269 | |||
270 | static int max17135_vcom_is_enabled(struct regulator_dev *reg) | ||
271 | { | ||
272 | struct max17135 *max17135 = rdev_get_drvdata(reg); | ||
273 | |||
274 | /* read VCOM regulator enable setting */ | ||
275 | if (max17135->pass_num == 1) { | ||
276 | int gpio = gpio_get_value(max17135->gpio_pmic_vcom_ctrl); | ||
277 | if (gpio == 0) | ||
278 | return 0; | ||
279 | else | ||
280 | return 1; | ||
281 | } else { | ||
282 | unsigned int reg_val; | ||
283 | |||
284 | max17135_reg_read(REG_MAX17135_ENABLE, ®_val); | ||
285 | reg_val &= BITFMASK(VCOM_ENABLE); | ||
286 | if (reg_val != 0) | ||
287 | return 1; | ||
288 | else | ||
289 | return 0; | ||
290 | } | ||
291 | } | ||
292 | |||
293 | static int max17135_is_power_good(struct max17135 *max17135) | ||
294 | { | ||
295 | unsigned int reg_val; | ||
296 | unsigned int fld_val; | ||
297 | |||
298 | max17135_reg_read(REG_MAX17135_FAULT, ®_val); | ||
299 | fld_val = (reg_val & BITFMASK(FAULT_POK)) >> FAULT_POK_LSH; | ||
300 | |||
301 | /* Check the POK bit */ | ||
302 | return fld_val; | ||
303 | } | ||
304 | |||
305 | static int max17135_wait_power_good(struct max17135 *max17135) | ||
306 | { | ||
307 | int i; | ||
308 | |||
309 | for (i = 0; i < max17135->max_wait * 3; i++) { | ||
310 | if (max17135_is_power_good(max17135)) | ||
311 | return 0; | ||
312 | |||
313 | msleep(1); | ||
314 | } | ||
315 | |||
316 | return -ETIMEDOUT; | ||
317 | } | ||
318 | |||
319 | static int max17135_display_enable(struct regulator_dev *reg) | ||
320 | { | ||
321 | struct max17135 *max17135 = rdev_get_drvdata(reg); | ||
322 | |||
323 | /* The Pass 1 parts cannot turn on the PMIC via I2C. */ | ||
324 | if (max17135->pass_num == 1) | ||
325 | gpio_set_value(max17135->gpio_pmic_wakeup, 1); | ||
326 | else { | ||
327 | unsigned int reg_val; | ||
328 | |||
329 | max17135_reg_read(REG_MAX17135_ENABLE, ®_val); | ||
330 | reg_val &= ~BITFMASK(ENABLE); | ||
331 | reg_val |= BITFVAL(ENABLE, 1); | ||
332 | max17135_reg_write(REG_MAX17135_ENABLE, reg_val); | ||
333 | } | ||
334 | |||
335 | return max17135_wait_power_good(max17135); | ||
336 | } | ||
337 | |||
338 | static int max17135_display_disable(struct regulator_dev *reg) | ||
339 | { | ||
340 | struct max17135 *max17135 = rdev_get_drvdata(reg); | ||
341 | |||
342 | if (max17135->pass_num == 1) | ||
343 | gpio_set_value(max17135->gpio_pmic_wakeup, 0); | ||
344 | else { | ||
345 | unsigned int reg_val; | ||
346 | |||
347 | max17135_reg_read(REG_MAX17135_ENABLE, ®_val); | ||
348 | reg_val &= ~BITFMASK(ENABLE); | ||
349 | max17135_reg_write(REG_MAX17135_ENABLE, reg_val); | ||
350 | } | ||
351 | |||
352 | msleep(max17135->max_wait); | ||
353 | |||
354 | return 0; | ||
355 | } | ||
356 | |||
357 | static int max17135_display_is_enabled(struct regulator_dev *reg) | ||
358 | { | ||
359 | struct max17135 *max17135 = rdev_get_drvdata(reg); | ||
360 | int gpio = gpio_get_value(max17135->gpio_pmic_wakeup); | ||
361 | |||
362 | if (gpio == 0) | ||
363 | return 0; | ||
364 | else | ||
365 | return 1; | ||
366 | } | ||
367 | |||
368 | static int max17135_v3p3_enable(struct regulator_dev *reg) | ||
369 | { | ||
370 | struct max17135 *max17135 = rdev_get_drvdata(reg); | ||
371 | |||
372 | gpio_set_value(max17135->gpio_pmic_v3p3, 1); | ||
373 | return 0; | ||
374 | } | ||
375 | |||
376 | static int max17135_v3p3_disable(struct regulator_dev *reg) | ||
377 | { | ||
378 | struct max17135 *max17135 = rdev_get_drvdata(reg); | ||
379 | |||
380 | gpio_set_value(max17135->gpio_pmic_v3p3, 0); | ||
381 | return 0; | ||
382 | } | ||
383 | |||
384 | static int max17135_v3p3_is_enabled(struct regulator_dev *reg) | ||
385 | { | ||
386 | struct max17135 *max17135 = rdev_get_drvdata(reg); | ||
387 | int gpio = gpio_get_value(max17135->gpio_pmic_v3p3); | ||
388 | |||
389 | if (gpio == 0) | ||
390 | return 0; | ||
391 | else | ||
392 | return 1; | ||
393 | } | ||
394 | |||
395 | /* | ||
396 | * Regulator operations | ||
397 | */ | ||
398 | |||
399 | static struct regulator_ops max17135_display_ops = { | ||
400 | .enable = max17135_display_enable, | ||
401 | .disable = max17135_display_disable, | ||
402 | .is_enabled = max17135_display_is_enabled, | ||
403 | }; | ||
404 | |||
405 | static struct regulator_ops max17135_gvdd_ops = { | ||
406 | }; | ||
407 | |||
408 | static struct regulator_ops max17135_gvee_ops = { | ||
409 | }; | ||
410 | |||
411 | static struct regulator_ops max17135_hvinn_ops = { | ||
412 | }; | ||
413 | |||
414 | static struct regulator_ops max17135_hvinp_ops = { | ||
415 | .enable = max17135_hvinp_enable, | ||
416 | .disable = max17135_hvinp_disable, | ||
417 | .get_voltage = max17135_hvinp_get_voltage, | ||
418 | .set_voltage = max17135_hvinp_set_voltage, | ||
419 | }; | ||
420 | |||
421 | static struct regulator_ops max17135_vcom_ops = { | ||
422 | .enable = max17135_vcom_enable, | ||
423 | .disable = max17135_vcom_disable, | ||
424 | .get_voltage = max17135_vcom_get_voltage, | ||
425 | .set_voltage = max17135_vcom_set_voltage, | ||
426 | .is_enabled = max17135_vcom_is_enabled, | ||
427 | }; | ||
428 | |||
429 | static struct regulator_ops max17135_vneg_ops = { | ||
430 | }; | ||
431 | |||
432 | static struct regulator_ops max17135_vpos_ops = { | ||
433 | }; | ||
434 | |||
435 | static struct regulator_ops max17135_v3p3_ops = { | ||
436 | .enable = max17135_v3p3_enable, | ||
437 | .disable = max17135_v3p3_disable, | ||
438 | .is_enabled = max17135_v3p3_is_enabled, | ||
439 | }; | ||
440 | |||
441 | |||
442 | /* | ||
443 | * Regulator descriptors | ||
444 | */ | ||
445 | static struct regulator_desc max17135_reg[MAX17135_NUM_REGULATORS] = { | ||
446 | { | ||
447 | .name = "DISPLAY", | ||
448 | .id = MAX17135_DISPLAY, | ||
449 | .ops = &max17135_display_ops, | ||
450 | .type = REGULATOR_VOLTAGE, | ||
451 | .owner = THIS_MODULE, | ||
452 | }, | ||
453 | { | ||
454 | .name = "GVDD", | ||
455 | .id = MAX17135_GVDD, | ||
456 | .ops = &max17135_gvdd_ops, | ||
457 | .type = REGULATOR_VOLTAGE, | ||
458 | .owner = THIS_MODULE, | ||
459 | }, | ||
460 | { | ||
461 | .name = "GVEE", | ||
462 | .id = MAX17135_GVEE, | ||
463 | .ops = &max17135_gvee_ops, | ||
464 | .type = REGULATOR_VOLTAGE, | ||
465 | .owner = THIS_MODULE, | ||
466 | }, | ||
467 | { | ||
468 | .name = "HVINN", | ||
469 | .id = MAX17135_HVINN, | ||
470 | .ops = &max17135_hvinn_ops, | ||
471 | .type = REGULATOR_VOLTAGE, | ||
472 | .owner = THIS_MODULE, | ||
473 | }, | ||
474 | { | ||
475 | .name = "HVINP", | ||
476 | .id = MAX17135_HVINP, | ||
477 | .ops = &max17135_hvinp_ops, | ||
478 | .type = REGULATOR_VOLTAGE, | ||
479 | .owner = THIS_MODULE, | ||
480 | }, | ||
481 | { | ||
482 | .name = "VCOM", | ||
483 | .id = MAX17135_VCOM, | ||
484 | .ops = &max17135_vcom_ops, | ||
485 | .type = REGULATOR_VOLTAGE, | ||
486 | .owner = THIS_MODULE, | ||
487 | }, | ||
488 | { | ||
489 | .name = "VNEG", | ||
490 | .id = MAX17135_VNEG, | ||
491 | .ops = &max17135_vneg_ops, | ||
492 | .type = REGULATOR_VOLTAGE, | ||
493 | .owner = THIS_MODULE, | ||
494 | }, | ||
495 | { | ||
496 | .name = "VPOS", | ||
497 | .id = MAX17135_VPOS, | ||
498 | .ops = &max17135_vpos_ops, | ||
499 | .type = REGULATOR_VOLTAGE, | ||
500 | .owner = THIS_MODULE, | ||
501 | }, | ||
502 | { | ||
503 | .name = "V3P3", | ||
504 | .id = MAX17135_V3P3, | ||
505 | .ops = &max17135_v3p3_ops, | ||
506 | .type = REGULATOR_VOLTAGE, | ||
507 | .owner = THIS_MODULE, | ||
508 | }, | ||
509 | }; | ||
510 | |||
511 | static void max17135_setup_timings(struct max17135 *max17135) | ||
512 | { | ||
513 | unsigned int reg_val; | ||
514 | |||
515 | int timing1, timing2, timing3, timing4, | ||
516 | timing5, timing6, timing7, timing8; | ||
517 | |||
518 | max17135_reg_read(REG_MAX17135_TIMING1, &timing1); | ||
519 | max17135_reg_read(REG_MAX17135_TIMING2, &timing2); | ||
520 | max17135_reg_read(REG_MAX17135_TIMING3, &timing3); | ||
521 | max17135_reg_read(REG_MAX17135_TIMING4, &timing4); | ||
522 | max17135_reg_read(REG_MAX17135_TIMING5, &timing5); | ||
523 | max17135_reg_read(REG_MAX17135_TIMING6, &timing6); | ||
524 | max17135_reg_read(REG_MAX17135_TIMING7, &timing7); | ||
525 | max17135_reg_read(REG_MAX17135_TIMING8, &timing8); | ||
526 | |||
527 | if ((timing1 != max17135->gvee_pwrup) || | ||
528 | (timing2 != max17135->vneg_pwrup) || | ||
529 | (timing3 != max17135->vpos_pwrup) || | ||
530 | (timing4 != max17135->gvdd_pwrup) || | ||
531 | (timing5 != max17135->gvdd_pwrdn) || | ||
532 | (timing6 != max17135->vpos_pwrdn) || | ||
533 | (timing7 != max17135->vneg_pwrdn) || | ||
534 | (timing8 != max17135->gvee_pwrdn)) { | ||
535 | max17135_reg_write(REG_MAX17135_TIMING1, max17135->gvee_pwrup); | ||
536 | max17135_reg_write(REG_MAX17135_TIMING2, max17135->vneg_pwrup); | ||
537 | max17135_reg_write(REG_MAX17135_TIMING3, max17135->vpos_pwrup); | ||
538 | max17135_reg_write(REG_MAX17135_TIMING4, max17135->gvdd_pwrup); | ||
539 | max17135_reg_write(REG_MAX17135_TIMING5, max17135->gvdd_pwrdn); | ||
540 | max17135_reg_write(REG_MAX17135_TIMING6, max17135->vpos_pwrdn); | ||
541 | max17135_reg_write(REG_MAX17135_TIMING7, max17135->vneg_pwrdn); | ||
542 | max17135_reg_write(REG_MAX17135_TIMING8, max17135->gvee_pwrdn); | ||
543 | |||
544 | reg_val = BITFVAL(CTRL_TIMING, true); /* shift to correct bit */ | ||
545 | max17135_reg_write(REG_MAX17135_PRGM_CTRL, reg_val); | ||
546 | } | ||
547 | } | ||
548 | |||
549 | #define CHECK_PROPERTY_ERROR_KFREE(prop) \ | ||
550 | do { \ | ||
551 | int ret = of_property_read_u32(max17135->dev->of_node, \ | ||
552 | #prop, &max17135->prop); \ | ||
553 | if (ret < 0) { \ | ||
554 | return ret; \ | ||
555 | } \ | ||
556 | } while (0); | ||
557 | |||
558 | #ifdef CONFIG_OF | ||
559 | static int max17135_pmic_dt_parse_pdata(struct platform_device *pdev, | ||
560 | struct max17135_platform_data *pdata) | ||
561 | { | ||
562 | struct max17135 *max17135 = dev_get_drvdata(pdev->dev.parent); | ||
563 | struct device_node *pmic_np, *regulators_np, *reg_np; | ||
564 | struct max17135_regulator_data *rdata; | ||
565 | int i, ret; | ||
566 | |||
567 | pmic_np = of_node_get(max17135->dev->of_node); | ||
568 | if (!pmic_np) { | ||
569 | dev_err(&pdev->dev, "could not find pmic sub-node\n"); | ||
570 | return -ENODEV; | ||
571 | } | ||
572 | |||
573 | regulators_np = of_find_node_by_name(pmic_np, "regulators"); | ||
574 | if (!regulators_np) { | ||
575 | dev_err(&pdev->dev, "could not find regulators sub-node\n"); | ||
576 | return -EINVAL; | ||
577 | } | ||
578 | |||
579 | pdata->num_regulators = of_get_child_count(regulators_np); | ||
580 | dev_dbg(&pdev->dev, "num_regulators %d\n", pdata->num_regulators); | ||
581 | |||
582 | rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) * | ||
583 | pdata->num_regulators, GFP_KERNEL); | ||
584 | if (!rdata) { | ||
585 | of_node_put(regulators_np); | ||
586 | dev_err(&pdev->dev, "could not allocate memory for" | ||
587 | "regulator data\n"); | ||
588 | return -ENOMEM; | ||
589 | } | ||
590 | |||
591 | pdata->regulators = rdata; | ||
592 | for_each_child_of_node(regulators_np, reg_np) { | ||
593 | for (i = 0; i < ARRAY_SIZE(max17135_reg); i++) | ||
594 | if (!of_node_cmp(reg_np->name, max17135_reg[i].name)) | ||
595 | break; | ||
596 | |||
597 | if (i == ARRAY_SIZE(max17135_reg)) { | ||
598 | dev_warn(&pdev->dev, "don't know how to configure" | ||
599 | "regulator %s\n", reg_np->name); | ||
600 | continue; | ||
601 | } | ||
602 | |||
603 | rdata->id = i; | ||
604 | rdata->initdata = of_get_regulator_init_data(&pdev->dev, | ||
605 | reg_np); | ||
606 | rdata->reg_node = reg_np; | ||
607 | rdata++; | ||
608 | } | ||
609 | of_node_put(regulators_np); | ||
610 | |||
611 | CHECK_PROPERTY_ERROR_KFREE(vneg_pwrup); | ||
612 | CHECK_PROPERTY_ERROR_KFREE(gvee_pwrup); | ||
613 | CHECK_PROPERTY_ERROR_KFREE(vpos_pwrup); | ||
614 | CHECK_PROPERTY_ERROR_KFREE(gvdd_pwrup); | ||
615 | CHECK_PROPERTY_ERROR_KFREE(gvdd_pwrdn); | ||
616 | CHECK_PROPERTY_ERROR_KFREE(vpos_pwrdn); | ||
617 | CHECK_PROPERTY_ERROR_KFREE(gvee_pwrdn); | ||
618 | CHECK_PROPERTY_ERROR_KFREE(vneg_pwrdn); | ||
619 | |||
620 | dev_dbg(&pdev->dev, "vneg_pwrup %d, vneg_pwrdn %d, vpos_pwrup %d," | ||
621 | "vpos_pwrdn %d, gvdd_pwrup %d, gvdd_pwrdn %d, gvee_pwrup %d," | ||
622 | "gvee_pwrdn %d\n", max17135->vneg_pwrup, max17135->vneg_pwrdn, | ||
623 | max17135->vpos_pwrup, max17135->vpos_pwrdn, | ||
624 | max17135->gvdd_pwrup, max17135->gvdd_pwrdn, | ||
625 | max17135->gvee_pwrup, max17135->gvee_pwrdn); | ||
626 | |||
627 | max17135->max_wait = max17135->vpos_pwrup + max17135->vneg_pwrup + | ||
628 | max17135->gvdd_pwrup + max17135->gvee_pwrup; | ||
629 | |||
630 | max17135->gpio_pmic_wakeup = of_get_named_gpio(pmic_np, | ||
631 | "gpio_pmic_wakeup", 0); | ||
632 | if (!gpio_is_valid(max17135->gpio_pmic_wakeup)) { | ||
633 | dev_err(&pdev->dev, "no epdc pmic wakeup pin available\n"); | ||
634 | goto err; | ||
635 | } | ||
636 | ret = devm_gpio_request_one(&pdev->dev, max17135->gpio_pmic_wakeup, | ||
637 | GPIOF_OUT_INIT_LOW, "epdc-pmic-wake"); | ||
638 | if (ret < 0) | ||
639 | goto err; | ||
640 | |||
641 | max17135->gpio_pmic_vcom_ctrl = of_get_named_gpio(pmic_np, | ||
642 | "gpio_pmic_vcom_ctrl", 0); | ||
643 | if (!gpio_is_valid(max17135->gpio_pmic_vcom_ctrl)) { | ||
644 | dev_err(&pdev->dev, "no epdc pmic vcom_ctrl pin available\n"); | ||
645 | goto err; | ||
646 | } | ||
647 | ret = devm_gpio_request_one(&pdev->dev, max17135->gpio_pmic_vcom_ctrl, | ||
648 | GPIOF_OUT_INIT_LOW, "epdc-vcom"); | ||
649 | if (ret < 0) | ||
650 | goto err; | ||
651 | |||
652 | max17135->gpio_pmic_v3p3 = of_get_named_gpio(pmic_np, | ||
653 | "gpio_pmic_v3p3", 0); | ||
654 | if (!gpio_is_valid(max17135->gpio_pmic_v3p3)) { | ||
655 | dev_err(&pdev->dev, "no epdc pmic v3p3 pin available\n"); | ||
656 | goto err; | ||
657 | } | ||
658 | ret = devm_gpio_request_one(&pdev->dev, max17135->gpio_pmic_v3p3, | ||
659 | GPIOF_OUT_INIT_LOW, "epdc-v3p3"); | ||
660 | if (ret < 0) | ||
661 | goto err; | ||
662 | |||
663 | max17135->gpio_pmic_intr = of_get_named_gpio(pmic_np, | ||
664 | "gpio_pmic_intr", 0); | ||
665 | if (!gpio_is_valid(max17135->gpio_pmic_intr)) { | ||
666 | dev_err(&pdev->dev, "no epdc pmic intr pin available\n"); | ||
667 | goto err; | ||
668 | } | ||
669 | ret = devm_gpio_request_one(&pdev->dev, max17135->gpio_pmic_intr, | ||
670 | GPIOF_IN, "epdc-pmic-int"); | ||
671 | if (ret < 0) | ||
672 | goto err; | ||
673 | |||
674 | max17135->gpio_pmic_pwrgood = of_get_named_gpio(pmic_np, | ||
675 | "gpio_pmic_pwrgood", 0); | ||
676 | if (!gpio_is_valid(max17135->gpio_pmic_pwrgood)) { | ||
677 | dev_err(&pdev->dev, "no epdc pmic pwrgood pin available\n"); | ||
678 | goto err; | ||
679 | } | ||
680 | ret = devm_gpio_request_one(&pdev->dev, max17135->gpio_pmic_pwrgood, | ||
681 | GPIOF_IN, "epdc-pwrstat"); | ||
682 | if (ret < 0) | ||
683 | goto err; | ||
684 | |||
685 | err: | ||
686 | return 0; | ||
687 | |||
688 | } | ||
689 | #else | ||
690 | static int max17135_pmic_dt_parse_pdata(struct platform_device *pdev, | ||
691 | struct max17135 *max17135) | ||
692 | { | ||
693 | return 0; | ||
694 | } | ||
695 | #endif /* !CONFIG_OF */ | ||
696 | |||
697 | /* | ||
698 | * Regulator init/probing/exit functions | ||
699 | */ | ||
700 | static int max17135_regulator_probe(struct platform_device *pdev) | ||
701 | { | ||
702 | struct max17135 *max17135 = dev_get_drvdata(pdev->dev.parent); | ||
703 | struct max17135_platform_data *pdata = max17135->pdata; | ||
704 | struct max17135_data *priv; | ||
705 | struct regulator_dev **rdev; | ||
706 | struct regulator_config config = { }; | ||
707 | int size, i, ret = 0; | ||
708 | |||
709 | if (max17135->dev->of_node) { | ||
710 | ret = max17135_pmic_dt_parse_pdata(pdev, pdata); | ||
711 | if (ret) | ||
712 | return ret; | ||
713 | } | ||
714 | priv = devm_kzalloc(&pdev->dev, sizeof(struct max17135_data), | ||
715 | GFP_KERNEL); | ||
716 | if (!priv) | ||
717 | return -ENOMEM; | ||
718 | |||
719 | size = sizeof(struct regulator_dev *) * pdata->num_regulators; | ||
720 | priv->rdev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); | ||
721 | if (!priv->rdev) | ||
722 | return -ENOMEM; | ||
723 | |||
724 | rdev = priv->rdev; | ||
725 | priv->num_regulators = pdata->num_regulators; | ||
726 | platform_set_drvdata(pdev, priv); | ||
727 | |||
728 | max17135->vcom_setup = false; | ||
729 | max17135->pass_num = max17135_pass_num; | ||
730 | max17135->vcom_uV = max17135_vcom; | ||
731 | |||
732 | for (i = 0; i < pdata->num_regulators; i++) { | ||
733 | int id = pdata->regulators[i].id; | ||
734 | |||
735 | config.dev = max17135->dev; | ||
736 | config.init_data = pdata->regulators[i].initdata; | ||
737 | config.driver_data = max17135; | ||
738 | config.of_node = pdata->regulators[i].reg_node; | ||
739 | |||
740 | rdev[i] = regulator_register(&max17135_reg[id], &config); | ||
741 | if (IS_ERR(rdev[i])) { | ||
742 | ret = PTR_ERR(rdev[i]); | ||
743 | dev_err(&pdev->dev, "regulator init failed for %d\n", | ||
744 | id); | ||
745 | rdev[i] = NULL; | ||
746 | goto err; | ||
747 | } | ||
748 | } | ||
749 | |||
750 | /* | ||
751 | * Set up PMIC timing values. | ||
752 | * Should only be done one time! Timing values may only be | ||
753 | * changed a limited number of times according to spec. | ||
754 | */ | ||
755 | max17135_setup_timings(max17135); | ||
756 | |||
757 | return 0; | ||
758 | err: | ||
759 | while (--i >= 0) | ||
760 | regulator_unregister(rdev[i]); | ||
761 | return ret; | ||
762 | } | ||
763 | |||
764 | static int max17135_regulator_remove(struct platform_device *pdev) | ||
765 | { | ||
766 | struct max17135_data *priv = platform_get_drvdata(pdev); | ||
767 | struct regulator_dev **rdev = priv->rdev; | ||
768 | int i; | ||
769 | |||
770 | for (i = 0; i < priv->num_regulators; i++) | ||
771 | regulator_unregister(rdev[i]); | ||
772 | return 0; | ||
773 | } | ||
774 | |||
775 | static const struct platform_device_id max17135_pmic_id[] = { | ||
776 | { "max17135-pmic", 0}, | ||
777 | { /* sentinel */ }, | ||
778 | }; | ||
779 | MODULE_DEVICE_TABLE(platform, max17135_pmic_id); | ||
780 | |||
781 | static struct platform_driver max17135_regulator_driver = { | ||
782 | .probe = max17135_regulator_probe, | ||
783 | .remove = max17135_regulator_remove, | ||
784 | .id_table = max17135_pmic_id, | ||
785 | .driver = { | ||
786 | .name = "max17135-pmic", | ||
787 | }, | ||
788 | }; | ||
789 | |||
790 | static int __init max17135_regulator_init(void) | ||
791 | { | ||
792 | return platform_driver_register(&max17135_regulator_driver); | ||
793 | } | ||
794 | subsys_initcall_sync(max17135_regulator_init); | ||
795 | |||
796 | static void __exit max17135_regulator_exit(void) | ||
797 | { | ||
798 | platform_driver_unregister(&max17135_regulator_driver); | ||
799 | } | ||
800 | module_exit(max17135_regulator_exit); | ||
801 | |||
802 | /* | ||
803 | * Parse user specified options (`max17135:') | ||
804 | * example: | ||
805 | * max17135:pass=2,vcom=-1250000 | ||
806 | */ | ||
807 | static int __init max17135_setup(char *options) | ||
808 | { | ||
809 | int ret; | ||
810 | char *opt; | ||
811 | while ((opt = strsep(&options, ",")) != NULL) { | ||
812 | if (!*opt) | ||
813 | continue; | ||
814 | if (!strncmp(opt, "pass=", 5)) { | ||
815 | ret = strict_strtoul(opt + 5, 0, &max17135_pass_num); | ||
816 | if (ret < 0) | ||
817 | return ret; | ||
818 | } | ||
819 | if (!strncmp(opt, "vcom=", 5)) { | ||
820 | int offs = 5; | ||
821 | if (opt[5] == '-') | ||
822 | offs = 6; | ||
823 | ret = strict_strtoul(opt + offs, 0, | ||
824 | (long *)&max17135_vcom); | ||
825 | if (ret < 0) | ||
826 | return ret; | ||
827 | max17135_vcom = -max17135_vcom; | ||
828 | } | ||
829 | } | ||
830 | |||
831 | return 1; | ||
832 | } | ||
833 | |||
834 | __setup("max17135:", max17135_setup); | ||
835 | |||
836 | /* Module information */ | ||
837 | MODULE_DESCRIPTION("MAX17135 regulator driver"); | ||
838 | MODULE_LICENSE("GPL"); | ||
diff --git a/include/linux/mfd/max17135.h b/include/linux/mfd/max17135.h new file mode 100644 index 000000000000..99c797ae1d57 --- /dev/null +++ b/include/linux/mfd/max17135.h | |||
@@ -0,0 +1,220 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
17 | * | ||
18 | */ | ||
19 | #ifndef __LINUX_REGULATOR_MAX17135_H_ | ||
20 | #define __LINUX_REGULATOR_MAX17135_H_ | ||
21 | |||
22 | /* | ||
23 | * PMIC Register Addresses | ||
24 | */ | ||
25 | enum { | ||
26 | REG_MAX17135_EXT_TEMP = 0x0, | ||
27 | REG_MAX17135_CONFIG, | ||
28 | REG_MAX17135_INT_TEMP = 0x4, | ||
29 | REG_MAX17135_STATUS, | ||
30 | REG_MAX17135_PRODUCT_REV, | ||
31 | REG_MAX17135_PRODUCT_ID, | ||
32 | REG_MAX17135_DVR, | ||
33 | REG_MAX17135_ENABLE, | ||
34 | REG_MAX17135_FAULT, /*0x0A*/ | ||
35 | REG_MAX17135_HVINP, | ||
36 | REG_MAX17135_PRGM_CTRL, | ||
37 | REG_MAX17135_TIMING1 = 0x10, /* Timing regs base address is 0x10 */ | ||
38 | REG_MAX17135_TIMING2, | ||
39 | REG_MAX17135_TIMING3, | ||
40 | REG_MAX17135_TIMING4, | ||
41 | REG_MAX17135_TIMING5, | ||
42 | REG_MAX17135_TIMING6, | ||
43 | REG_MAX17135_TIMING7, | ||
44 | REG_MAX17135_TIMING8, | ||
45 | }; | ||
46 | #define MAX17135_REG_NUM 21 | ||
47 | #define MAX17135_MAX_REGISTER 0xFF | ||
48 | |||
49 | /* | ||
50 | * Bitfield macros that use rely on bitfield width/shift information. | ||
51 | */ | ||
52 | #define BITFMASK(field) (((1U << (field ## _WID)) - 1) << (field ## _LSH)) | ||
53 | #define BITFVAL(field, val) ((val) << (field ## _LSH)) | ||
54 | #define BITFEXT(var, bit) ((var & BITFMASK(bit)) >> (bit ## _LSH)) | ||
55 | |||
56 | /* | ||
57 | * Shift and width values for each register bitfield | ||
58 | */ | ||
59 | #define EXT_TEMP_LSH 7 | ||
60 | #define EXT_TEMP_WID 9 | ||
61 | |||
62 | #define THERMAL_SHUTDOWN_LSH 0 | ||
63 | #define THERMAL_SHUTDOWN_WID 1 | ||
64 | |||
65 | #define INT_TEMP_LSH 7 | ||
66 | #define INT_TEMP_WID 9 | ||
67 | |||
68 | #define STAT_BUSY_LSH 0 | ||
69 | #define STAT_BUSY_WID 1 | ||
70 | #define STAT_OPEN_LSH 1 | ||
71 | #define STAT_OPEN_WID 1 | ||
72 | #define STAT_SHRT_LSH 2 | ||
73 | #define STAT_SHRT_WID 1 | ||
74 | |||
75 | #define PROD_REV_LSH 0 | ||
76 | #define PROD_REV_WID 8 | ||
77 | |||
78 | #define PROD_ID_LSH 0 | ||
79 | #define PROD_ID_WID 8 | ||
80 | |||
81 | #define DVR_LSH 0 | ||
82 | #define DVR_WID 8 | ||
83 | |||
84 | #define ENABLE_LSH 0 | ||
85 | #define ENABLE_WID 1 | ||
86 | #define VCOM_ENABLE_LSH 1 | ||
87 | #define VCOM_ENABLE_WID 1 | ||
88 | |||
89 | #define FAULT_FBPG_LSH 0 | ||
90 | #define FAULT_FBPG_WID 1 | ||
91 | #define FAULT_HVINP_LSH 1 | ||
92 | #define FAULT_HVINP_WID 1 | ||
93 | #define FAULT_HVINN_LSH 2 | ||
94 | #define FAULT_HVINN_WID 1 | ||
95 | #define FAULT_FBNG_LSH 3 | ||
96 | #define FAULT_FBNG_WID 1 | ||
97 | #define FAULT_HVINPSC_LSH 4 | ||
98 | #define FAULT_HVINPSC_WID 1 | ||
99 | #define FAULT_HVINNSC_LSH 5 | ||
100 | #define FAULT_HVINNSC_WID 1 | ||
101 | #define FAULT_OT_LSH 6 | ||
102 | #define FAULT_OT_WID 1 | ||
103 | #define FAULT_POK_LSH 7 | ||
104 | #define FAULT_POK_WID 1 | ||
105 | |||
106 | #define HVINP_LSH 0 | ||
107 | #define HVINP_WID 4 | ||
108 | |||
109 | #define CTRL_DVR_LSH 0 | ||
110 | #define CTRL_DVR_WID 1 | ||
111 | #define CTRL_TIMING_LSH 1 | ||
112 | #define CTRL_TIMING_WID 1 | ||
113 | |||
114 | #define TIMING1_LSH 0 | ||
115 | #define TIMING1_WID 8 | ||
116 | #define TIMING2_LSH 0 | ||
117 | #define TIMING2_WID 8 | ||
118 | #define TIMING3_LSH 0 | ||
119 | #define TIMING3_WID 8 | ||
120 | #define TIMING4_LSH 0 | ||
121 | #define TIMING4_WID 8 | ||
122 | #define TIMING5_LSH 0 | ||
123 | #define TIMING5_WID 8 | ||
124 | #define TIMING6_LSH 0 | ||
125 | #define TIMING6_WID 8 | ||
126 | #define TIMING7_LSH 0 | ||
127 | #define TIMING7_WID 8 | ||
128 | #define TIMING8_LSH 0 | ||
129 | #define TIMING8_WID 8 | ||
130 | |||
131 | struct max17135 { | ||
132 | /* chip revision */ | ||
133 | int rev; | ||
134 | |||
135 | struct device *dev; | ||
136 | struct max17135_platform_data *pdata; | ||
137 | |||
138 | /* Platform connection */ | ||
139 | struct i2c_client *i2c_client; | ||
140 | |||
141 | /* Timings */ | ||
142 | unsigned int gvee_pwrup; | ||
143 | unsigned int vneg_pwrup; | ||
144 | unsigned int vpos_pwrup; | ||
145 | unsigned int gvdd_pwrup; | ||
146 | unsigned int gvdd_pwrdn; | ||
147 | unsigned int vpos_pwrdn; | ||
148 | unsigned int vneg_pwrdn; | ||
149 | unsigned int gvee_pwrdn; | ||
150 | |||
151 | /* GPIOs */ | ||
152 | int gpio_pmic_pwrgood; | ||
153 | int gpio_pmic_vcom_ctrl; | ||
154 | int gpio_pmic_wakeup; | ||
155 | int gpio_pmic_v3p3; | ||
156 | int gpio_pmic_intr; | ||
157 | |||
158 | /* MAX17135 part variables */ | ||
159 | int pass_num; | ||
160 | int vcom_uV; | ||
161 | |||
162 | /* One-time VCOM setup marker */ | ||
163 | bool vcom_setup; | ||
164 | |||
165 | /* powerup/powerdown wait time */ | ||
166 | int max_wait; | ||
167 | }; | ||
168 | |||
169 | enum { | ||
170 | /* In alphabetical order */ | ||
171 | MAX17135_DISPLAY, /* virtual master enable */ | ||
172 | MAX17135_GVDD, | ||
173 | MAX17135_GVEE, | ||
174 | MAX17135_HVINN, | ||
175 | MAX17135_HVINP, | ||
176 | MAX17135_VCOM, | ||
177 | MAX17135_VNEG, | ||
178 | MAX17135_VPOS, | ||
179 | MAX17135_V3P3, | ||
180 | MAX17135_NUM_REGULATORS, | ||
181 | }; | ||
182 | |||
183 | /* | ||
184 | * Declarations | ||
185 | */ | ||
186 | struct regulator_init_data; | ||
187 | struct max17135_regulator_data; | ||
188 | |||
189 | struct max17135_platform_data { | ||
190 | unsigned int gvee_pwrup; | ||
191 | unsigned int vneg_pwrup; | ||
192 | unsigned int vpos_pwrup; | ||
193 | unsigned int gvdd_pwrup; | ||
194 | unsigned int gvdd_pwrdn; | ||
195 | unsigned int vpos_pwrdn; | ||
196 | unsigned int vneg_pwrdn; | ||
197 | unsigned int gvee_pwrdn; | ||
198 | int gpio_pmic_pwrgood; | ||
199 | int gpio_pmic_vcom_ctrl; | ||
200 | int gpio_pmic_wakeup; | ||
201 | int gpio_pmic_v3p3; | ||
202 | int gpio_pmic_intr; | ||
203 | int pass_num; | ||
204 | int vcom_uV; | ||
205 | |||
206 | /* PMIC */ | ||
207 | struct max17135_regulator_data *regulators; | ||
208 | int num_regulators; | ||
209 | }; | ||
210 | |||
211 | struct max17135_regulator_data { | ||
212 | int id; | ||
213 | struct regulator_init_data *initdata; | ||
214 | struct device_node *reg_node; | ||
215 | }; | ||
216 | |||
217 | int max17135_reg_read(int reg_num, unsigned int *reg_val); | ||
218 | int max17135_reg_write(int reg_num, const unsigned int reg_val); | ||
219 | |||
220 | #endif | ||
diff --git a/include/linux/pmic_status.h b/include/linux/pmic_status.h new file mode 100644 index 000000000000..7ba42f6221a3 --- /dev/null +++ b/include/linux/pmic_status.h | |||
@@ -0,0 +1,82 @@ | |||
1 | /* | ||
2 | * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | */ | ||
4 | |||
5 | /* | ||
6 | * The code contained herein is licensed under the GNU Lesser General | ||
7 | * Public License. You may obtain a copy of the GNU Lesser General | ||
8 | * Public License Version 2.1 or later at the following locations: | ||
9 | * | ||
10 | * http://www.opensource.org/licenses/lgpl-license.html | ||
11 | * http://www.gnu.org/copyleft/lgpl.html | ||
12 | */ | ||
13 | #ifndef __ASM_ARCH_MXC_PMIC_STATUS_H__ | ||
14 | #define __ASM_ARCH_MXC_PMIC_STATUS_H__ | ||
15 | #include <asm-generic/errno-base.h> | ||
16 | #ifdef __KERNEL__ | ||
17 | #include <asm/uaccess.h> /* copy_{from,to}_user() */ | ||
18 | #endif | ||
19 | /*! | ||
20 | * @file arch-mxc/pmic_status.h | ||
21 | * @brief PMIC APIs return code definition. | ||
22 | * | ||
23 | * @ingroup PMIC_CORE | ||
24 | */ | ||
25 | |||
26 | /*! | ||
27 | * @enum PMIC_STATUS | ||
28 | * @brief Define return values for all PMIC APIs. | ||
29 | * | ||
30 | * These return values are used by all of the PMIC APIs. | ||
31 | * | ||
32 | * @ingroup PMIC | ||
33 | */ | ||
34 | typedef enum { | ||
35 | PMIC_SUCCESS = 0, /*!< The requested operation was successfully | ||
36 | completed. */ | ||
37 | PMIC_ERROR = -1, /*!< The requested operation could not be completed | ||
38 | due to an error. */ | ||
39 | PMIC_PARAMETER_ERROR = -2, /*!< The requested operation failed because | ||
40 | one or more of the parameters was | ||
41 | invalid. */ | ||
42 | PMIC_NOT_SUPPORTED = -3, /*!< The requested operation could not be | ||
43 | completed because the PMIC hardware | ||
44 | does not support it. */ | ||
45 | PMIC_SYSTEM_ERROR_EINTR = -EINTR, | ||
46 | |||
47 | PMIC_MALLOC_ERROR = -5, /*!< Error in malloc function */ | ||
48 | PMIC_UNSUBSCRIBE_ERROR = -6, /*!< Error in un-subscribe event */ | ||
49 | PMIC_EVENT_NOT_SUBSCRIBED = -7, /*!< Event occur and not subscribed */ | ||
50 | PMIC_EVENT_CALL_BACK = -8, /*!< Error - bad call back */ | ||
51 | PMIC_CLIENT_NBOVERFLOW = -9, /*!< The requested operation could not be | ||
52 | completed because there are too many | ||
53 | PMIC client requests */ | ||
54 | } PMIC_STATUS; | ||
55 | |||
56 | /* | ||
57 | * Bitfield macros that use rely on bitfield width/shift information. | ||
58 | */ | ||
59 | #define BITFMASK(field) (((1U << (field ## _WID)) - 1) << (field ## _LSH)) | ||
60 | #define BITFVAL(field, val) ((val) << (field ## _LSH)) | ||
61 | #define BITFEXT(var, bit) ((var & BITFMASK(bit)) >> (bit ## _LSH)) | ||
62 | |||
63 | /* | ||
64 | * Macros implementing error handling | ||
65 | */ | ||
66 | #define CHECK_ERROR(a) \ | ||
67 | do { \ | ||
68 | int ret = (a); \ | ||
69 | if (ret != PMIC_SUCCESS) \ | ||
70 | return ret; \ | ||
71 | } while (0) | ||
72 | |||
73 | #define CHECK_ERROR_KFREE(func, freeptrs) \ | ||
74 | do { \ | ||
75 | int ret = (func); \ | ||
76 | if (ret != PMIC_SUCCESS) { \ | ||
77 | freeptrs; \ | ||
78 | return ret; \ | ||
79 | } \ | ||
80 | } while (0); | ||
81 | |||
82 | #endif /* __ASM_ARCH_MXC_PMIC_STATUS_H__ */ | ||