summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 7cad98b)
raw | patch | inline | side by side (parent: 7cad98b)
author | Milo Kim <milo.kim@ti.com> | |
Wed, 25 Feb 2015 07:27:32 +0000 (16:27 +0900) | ||
committer | Milo Kim <milo.kim@ti.com> | |
Wed, 25 Feb 2015 07:27:32 +0000 (16:27 +0900) |
- mfd, regulator and backlight driver
- Device tree bindings included
- Example code for LCD bias regulator consumer.
Signed-off-by: Milo Kim <milo.kim@ti.com>
- Device tree bindings included
- Example code for LCD bias regulator consumer.
Signed-off-by: Milo Kim <milo.kim@ti.com>
diff --git a/Documentation/devicetree/bindings/mfd/lm3632.txt b/Documentation/devicetree/bindings/mfd/lm3632.txt
index f670058c8c67868bfe4dd6e0ecc8fafc5e92a270..3ab8ef544213c988ace8c1f6ff9d9367205e803f 100644 (file)
Required properties:
- compatible: "ti,lm3632"
Required properties:
- compatible: "ti,lm3632"
- - reg: I2C slave address. 0x29.
- - ti,en-gpio: GPIO number of LM3632 nRST pin.
+ - reg: I2C slave address. 0x11.
+ - ti,en-gpio: GPIO number of LM3632 EN pin.
-LM3632 consists of two sub-devices, lm3632-regulator and lm3632-bl.
+LM3632 consists of lm3632-regulator and lm3632-bl.
For the LM3632 regulator properties please refer to:
Documentation/devicetree/bindings/regulator/lm3632-regulator.txt
For the LM3632 regulator properties please refer to:
Documentation/devicetree/bindings/regulator/lm3632-regulator.txt
compatible = "ti,lm3632";
reg = <0x11>;
compatible = "ti,lm3632";
reg = <0x11>;
- /* GPIO134 for HWEN pin */
- ti,en-gpio = <&gpio5 6 0>;
+ /* GPIO for EN pin */
+ ti,en-gpio = <&gpio0 3 0>;
- /* Only Vpos and Vneg are used with LCD boost */
+ /* Vpos and Vneg are used with LCD boost */
regulators {
compatible = "ti,lm3632-regulator";
regulators {
compatible = "ti,lm3632-regulator";
+ /* GPIOs for LCM_EN1 and LCM_EN2 pins */
+ ti,lcm-en1-gpio = <&gpio0 2 0>;
+ ti,lcm-en2-gpio = <&gpio0 4 0>;
+
vboost {
regulator-name = "lcd_boost";
regulator-min-microvolt = <4500000>;
vboost {
regulator-name = "lcd_boost";
regulator-min-microvolt = <4500000>;
- regulator-max-microvolt = <6350000>;
+ regulator-max-microvolt = <6400000>;
regulator-always-on;
};
regulator-always-on;
};
};
};
};
};
- /* Backlight mode is I2C + PWM, two strings used */
+ /* Backlight mode is PWM, two strings used */
backlight {
compatible = "ti,lm3632-backlight";
bl-name = "lcd";
full-strings-used;
backlight {
compatible = "ti,lm3632-backlight";
bl-name = "lcd";
full-strings-used;
- mode-comb1;
+
+ pwm-period = <10000>;
+ pwm-max-brightness = <1637>; /* 20mA */
};
};
};
};
diff --git a/Documentation/devicetree/bindings/regulator/lm3632-regulator.txt b/Documentation/devicetree/bindings/regulator/lm3632-regulator.txt
index 7edb7bae5c58dca8fd314f0eae61aa256f92f872..fa9531d366fffad76d729cf0f3ba904a964363d5 100644 (file)
- Regulator init data from of-regulator structure.
Please refer to regulator.txt in this directory.
- Regulator init data from of-regulator structure.
Please refer to regulator.txt in this directory.
+Optional properties:
+ Two GPIO pins are used for enabling/disabling VPOS and VNEG.
+ These properties can be ignored if two LDOs are controlled through the I2C register.
+ - ti,lcm-en1-gpio: GPIO number of LCM_EN1 pin.
+ - ti,lcm-en2-gpio: GPIO number of LCM_EN2 pin.
+
Example:
Example:
-&i2c4 {
- clock-frequency = <400000>;
-
- lm3632@11 {
- compatible = "ti,lm3632";
- reg = <0x29>;
-
- /* GPIO134 for HWEN pin */
- ti,en-gpio = <&gpio5 6 0>;
-
- regulators {
- compatible = "ti,lm3632-regulator";
-
- vboost {
- regulator-name = "lcd_boost";
- regulator-min-microvolt = <4500000>;
- regulator-max-microvolt = <6350000>;
- regulator-always-on;
- };
-
- vcont {
- regulator-name = "lcd_cont";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <3300000>;
- };
-
- voref {
- regulator-compatible = "voref";
- regulator-name = "lcd_oref";
- regulator-min-microvolt = <4000000>;
- regulator-max-microvolt = <6000000>;
- };
-
- vpos {
- regulator-name = "lcd_vpos";
- regulator-min-microvolt = <4000000>;
- regulator-max-microvolt = <6000000>;
- regulator-boot-on;
- };
-
- vneg {
- regulator-name = "lcd_vneg";
- regulator-min-microvolt = <4000000>;
- regulator-max-microvolt = <6000000>;
- regulator-boot-on;
- };
+lm3632@11 {
+ compatible = "ti,lm3632";
+ reg = <0x11>;
+
+ ti,en-gpio = <&gpio0 3 0>;
+
+ /* Vpos and Vneg are used with LCD boost */
+ regulators {
+ compatible = "ti,lm3632-regulator";
+
+ /* GPIOs for LCM_EN1 and LCM_EN2 pins */
+ ti,lcm-en1-gpio = <&gpio0 2 0>;
+ ti,lcm-en2-gpio = <&gpio0 4 0>;
+
+ vboost {
+ regulator-name = "lcd_boost";
+ regulator-min-microvolt = <4500000>;
+ regulator-max-microvolt = <6400000>;
+ regulator-always-on;
+ };
+
+ vpos {
+ regulator-name = "lcd_vpos";
+ regulator-min-microvolt = <4000000>;
+ regulator-max-microvolt = <6000000>;
+ regulator-boot-on;
+ };
+
+ vneg {
+ regulator-name = "lcd_vneg";
+ regulator-min-microvolt = <4000000>;
+ regulator-max-microvolt = <6000000>;
+ regulator-boot-on;
};
};
+ };
};
};
diff --git a/Documentation/devicetree/bindings/video/backlight/lm3632_bl.txt b/Documentation/devicetree/bindings/video/backlight/lm3632_bl.txt
index 256b053d3bfc0c1279886828016f80d3ce8bee33..c09b911d7557a86898d7ac1e6d9faa26c491736f 100644 (file)
Optional properties:
- bl-name: Backlight device name
- full-strings-used: Define it in case of two LED strings used.
Optional properties:
- bl-name: Backlight device name
- full-strings-used: Define it in case of two LED strings used.
- - mode-pwm-only: PWM input mode
- or mode-comb1: I2C x PWM befoer sloping
- or mode-comb2: Sloped I2C x PWM
- The default mode is the I2C only.
- - initial-brightness: Initial brightness value
PWM specific optional properties:
- pwm-period: PWM period value. Define it in case of PWM based control mode.
PWM specific optional properties:
- pwm-period: PWM period value. Define it in case of PWM based control mode.
- - pwms and pwm-names: Please refer to Documentation/devicetree/bindings/pwm/pwm.txt.
+ If this property is not defined, then brightness control mode is I2C.
+ - pwm-max-brightness: Max current value in register 0x04 and 0x05.
+ Range is from 0 to 2047.
+Example:
+lm3632@11 {
+ compatible = "ti,lm3632";
+ reg = <0x11>;
-Example 1:
-Brightness is I2C only mode. Backlight device name is 'lcd'.
+ ti,en-gpio = <&gpio0 3 0>;
-&i2c4 {
- clock-frequency = <400000>;
+ /* Backlight mode is PWM, two strings used */
+ backlight {
+ compatible = "ti,lm3632-backlight";
- lm3632@11 {
- compatible = "ti,lm3632";
- reg = <0x11>;
+ bl-name = "lcd";
+ full-strings-used;
- /* GPIO134 for HWEN pin */
- ti,en-gpio = <&gpio5 6 0>;
-
- backlight {
- compatible = "ti,lm3632-backlight";
- bl-name = "lcd";
- full-strings-used;
- };
-};
-
-Example 2:
-LM3632 brightness is controlled by PWM3943 controller.
-PWM3943 is a PWM controller. PWM#1 is port number of PMW3943.
-
-&i2c4 {
- clock-frequency = <400000>;
-
- lm3632@11 {
- compatible = "ti,lm3632";
- reg = <0x11>;
-
- /* GPIO134 for HWEN pin */
- ti,en-gpio = <&gpio5 6 0>;
-
- backlight {
- compatible = "ti,lm3632-backlight";
- bl-name = "lcd";
- full-strings-used;
- mode-pwm-only;
-
- pwm-period = <10000>;
-
- pwms = <&pwm3943 1 10000>;
- pwm-names = "lm3632-backlight";
- };
+ pwm-period = <10000>;
+ pwm-max-brightness = <1637>; /* 20mA */
+ };
};
};
diff --git a/Examples/board-plat-lm3631.c b/Examples/board-plat-lm3631.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Platform Specific LM3631 Example
- *
- * Copyright (C) 2013 Texas Instruments
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/mfd/lm3631.h>
-#include <linux/pwm.h>
-
-#include "mux.h"
-#include "board-plat-lm3631.h"
-
-static struct regulator_consumer_supply lcd_vboost[] = {
- REGULATOR_SUPPLY("lcd_boost", NULL),
-};
-
-static struct regulator_consumer_supply lcd_vio[] = {
- REGULATOR_SUPPLY("lcd_io", NULL),
-};
-
-static struct regulator_consumer_supply lcd_vpos[] = {
- REGULATOR_SUPPLY("lcd_vpos", NULL),
-};
-
-static struct regulator_consumer_supply lcd_vneg[] = {
- REGULATOR_SUPPLY("lcd_vneg", NULL),
-};
-
-static struct regulator_consumer_supply lcd_vgamma[] = {
- REGULATOR_SUPPLY("lcd_gamma", NULL),
-};
-
-struct regulator_init_data lcd_boost = {
- .constraints = {
- .name = "LCD_BOOST",
- .min_uV = 4500000,
- .max_uV = 6350000,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
- .always_on = 1,
- },
- .num_consumer_supplies = ARRAY_SIZE(lcd_vboost),
- .consumer_supplies = lcd_vboost,
-};
-
-struct regulator_init_data lcd_cont = {
- .constraints = {
- .name = "LCD_CONT",
- .min_uV = 1800000,
- .max_uV = 3300000,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
- REGULATOR_CHANGE_STATUS,
- },
- .num_consumer_supplies = ARRAY_SIZE(lcd_vio),
- .consumer_supplies = lcd_vio,
-};
-
-struct regulator_init_data lcd_oref = {
- .constraints = {
- .name = "LCD_OREF",
- .min_uV = 4000000,
- .max_uV = 6000000,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
- REGULATOR_CHANGE_STATUS,
- },
- .num_consumer_supplies = ARRAY_SIZE(lcd_vgamma),
- .consumer_supplies = lcd_vgamma,
-};
-
-struct regulator_init_data lcd_pos = {
- .constraints = {
- .name = "LCD_VPOS",
- .min_uV = 4000000,
- .max_uV = 6000000,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
- REGULATOR_CHANGE_STATUS,
- .boot_on = 1,
- },
- .num_consumer_supplies = ARRAY_SIZE(lcd_vpos),
- .consumer_supplies = lcd_vpos,
-};
-
-struct regulator_init_data lcd_neg = {
- .constraints = {
- .name = "LCD_VNEG",
- .min_uV = 4000000,
- .max_uV = 6000000,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
- REGULATOR_CHANGE_STATUS,
- .boot_on = 1,
- },
- .num_consumer_supplies = ARRAY_SIZE(lcd_vneg),
- .consumer_supplies = lcd_vneg,
-};
-
-struct lm3631_backlight_platform_data lm3631_bl_pdata = {
- .name = "lcd-bl",
- .is_full_strings = true,
- .mode = LM3631_COMB1,
-};
-
-#define LM3631_EN_GPIO 134
-static struct lm3631_platform_data lm3631_pdata = {
- .en_gpio = LM3631_EN_GPIO,
- .regulator_data = {
- &lcd_boost,
- &lcd_cont,
- &lcd_oref,
- &lcd_pos,
- &lcd_neg,
- },
- .bl_pdata = &lm3631_bl_pdata,
-};
-
-static struct i2c_board_info __initdata led_i2c_boardinfo[] = {
- {
- I2C_BOARD_INFO("lm3631", 0x29),
- .platform_data = &lm3631_pdata,
- },
-};
-
-int plat_lm3631_init(void)
-{
- i2c_register_board_info(4, led_i2c_boardinfo,
- ARRAY_SIZE(led_i2c_boardinfo));
- return 0;
-}
index a6705b949e7a0a5042e48c3590f154d85d70579d..27be5e1e1176205ea8a8086e4a07878994dec3a7 100644 (file)
--- a/Examples/lm-lcd-driver.c
+++ b/Examples/lm-lcd-driver.c
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
-#define LCD_BOOST_VOUT 5800000
+#define LCD_BOOST_VOUT 6000000
#define LCD_BIAS_VOUT 5500000
enum lcd_ldo_id {
#define LCD_BIAS_VOUT 5500000
enum lcd_ldo_id {
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 3d250c5c291fcf1be5699124fa4e2f0409364ba4..27355da5eeba6151909cc1622e36dec8f5325cd9 100644 (file)
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
LM3631 has 2 strings for backlight with 5 regulators for LCD bias.
config MFD_LM3632
LM3631 has 2 strings for backlight with 5 regulators for LCD bias.
config MFD_LM3632
- tristate "TI LM3632 Backlight and Bias Power Driver"
+ tristate "TI LM3632 Backlight with Bias Power and Flash Driver"
depends on I2C
select MFD_CORE
select REGMAP_I2C
help
Say yes here to enable support for TI LM3632 chip.
depends on I2C
select MFD_CORE
select REGMAP_I2C
help
Say yes here to enable support for TI LM3632 chip.
- LM3632 has 2 strings for backlight with 5 regulators for LCD bias.
+ LM3632 consists of 2 strings backlight with 3 regulators for LCD bias
+ and flash LED driver.
config MFD_AAT2870_CORE
bool "AnalogicTech AAT2870"
config MFD_AAT2870_CORE
bool "AnalogicTech AAT2870"
diff --git a/drivers/mfd/lm3632.c b/drivers/mfd/lm3632.c
index 8b2401f164367036f53bb939df1ee0969ce96b26..9bc32ccf014f0dc164288dc7b59459d7b302a193 100644 (file)
--- a/drivers/mfd/lm3632.c
+++ b/drivers/mfd/lm3632.c
}
static struct mfd_cell lm3632_devs[] = {
}
static struct mfd_cell lm3632_devs[] = {
- /* 5 Regulators */
+ /* 3 Regulators */
LM3632_DEV_LCD_BIAS(1),
LM3632_DEV_LCD_BIAS(2),
LM3632_DEV_LCD_BIAS(3),
LM3632_DEV_LCD_BIAS(1),
LM3632_DEV_LCD_BIAS(2),
LM3632_DEV_LCD_BIAS(3),
- LM3632_DEV_LCD_BIAS(4),
- LM3632_DEV_LCD_BIAS(5),
/* Backlight */
LM3632_DEV_BL,
/* Backlight */
LM3632_DEV_BL,
usleep_range(1000, 1500);
usleep_range(1000, 1500);
+ return 0;
+/*
return lm3632_update_bits(lm3632, LM3632_REG_DEVCTRL,
LM3632_LCD_EN_MASK,
1 << LM3632_LCD_EN_SHIFT);
return lm3632_update_bits(lm3632, LM3632_REG_DEVCTRL,
LM3632_LCD_EN_MASK,
1 << LM3632_LCD_EN_SHIFT);
+*/
}
static void lm3632_deinit_device(struct lm3632 *lm3632)
}
static void lm3632_deinit_device(struct lm3632 *lm3632)
index 36b821a3ad7970cfda61ecec71b25fe22f739fa7..90b68a0b09ad32966e7d3f9fc3fbdf2f6fc2bb45 100644 (file)
*
* Copyright 2015 Texas Instruments
*
*
* Copyright 2015 Texas Instruments
*
- * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
+ * Author: Milo Kim <milo.kim@ti.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
#include <linux/mfd/lm3632.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/mfd/lm3632.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/of_gpio.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>
#include <linux/slab.h>
-#define ENABLE_TIME_USEC 1000
-
enum lm3632_regulator_id {
LM3632_REGULATOR_BOOST,
enum lm3632_regulator_id {
LM3632_REGULATOR_BOOST,
- LM3632_LDO_CONT,
- LM3632_LDO_OREF,
LM3632_LDO_POS,
LM3632_LDO_NEG,
};
struct lm3632_regulator {
LM3632_LDO_POS,
LM3632_LDO_NEG,
};
struct lm3632_regulator {
+ int ena_gpio;
struct lm3632 *lm3632;
struct regulator_desc *desc;
struct regulator_dev *regulator;
struct lm3632 *lm3632;
struct regulator_desc *desc;
struct regulator_dev *regulator;
4900000, 4950000, 5000000, 5050000, 5100000, 5150000, 5200000, 5250000,
5300000, 5350000, 5400000, 5450000, 5500000, 5550000, 5600000, 5650000,
5700000, 5750000, 5800000, 5850000, 5900000, 5950000, 6000000, 6050000,
4900000, 4950000, 5000000, 5050000, 5100000, 5150000, 5200000, 5250000,
5300000, 5350000, 5400000, 5450000, 5500000, 5550000, 5600000, 5650000,
5700000, 5750000, 5800000, 5850000, 5900000, 5950000, 6000000, 6050000,
- 6100000, 6150000, 6200000, 6250000, 6300000, 6350000,
-};
-
-static const int lm3632_ldo_cont_vtbl[] = {
- 1800000, 2300000, 2800000, 3300000,
+ 6100000, 6150000, 6200000, 6250000, 6300000, 6350000, 6400000,
};
};
-static const int lm3632_ldo_target_vtbl[] = {
+static const int lm3632_ldo_vtbl[] = {
4000000, 4050000, 4100000, 4150000, 4200000, 4250000, 4300000, 4350000,
4400000, 4450000, 4500000, 4550000, 4600000, 4650000, 4700000, 4750000,
4800000, 4850000, 4900000, 4950000, 5000000, 5050000, 5100000, 5150000,
4000000, 4050000, 4100000, 4150000, 4200000, 4250000, 4300000, 4350000,
4400000, 4450000, 4500000, 4550000, 4600000, 4650000, 4700000, 4750000,
4800000, 4850000, 4900000, 4950000, 5000000, 5050000, 5100000, 5150000,
6000000,
};
6000000,
};
-const int ldo_cont_enable_time[] = {
- 0, 2000, 5000, 10000, 20000, 50000, 100000, 200000,
-};
-
-static int lm3632_regulator_enable_time(struct regulator_dev *rdev)
-{
- struct lm3632_regulator *lm3632_regulator = rdev_get_drvdata(rdev);
- enum lm3632_regulator_id id = rdev_get_id(rdev);
- u8 val, addr, mask;
-
- switch (id) {
- case LM3632_LDO_CONT:
- addr = LM3632_REG_ENTIME_VCONT;
- mask = LM3632_ENTIME_CONT_MASK;
- break;
- case LM3632_LDO_OREF:
- addr = LM3632_REG_ENTIME_VOREF;
- mask = LM3632_ENTIME_MASK;
- break;
- case LM3632_LDO_POS:
- addr = LM3632_REG_ENTIME_VPOS;
- mask = LM3632_ENTIME_MASK;
- break;
- case LM3632_LDO_NEG:
- addr = LM3632_REG_ENTIME_VNEG;
- mask = LM3632_ENTIME_MASK;
- break;
- default:
- return -EINVAL;
- }
-
- if (lm3632_read_byte(lm3632_regulator->lm3632, addr, &val))
- return -EINVAL;
-
- val = (val & mask) >> LM3632_ENTIME_SHIFT;
-
- if (id == LM3632_LDO_CONT)
- return ldo_cont_enable_time[val];
- else
- return ENABLE_TIME_USEC * val;
-}
-
static struct regulator_ops lm3632_boost_voltage_table_ops = {
.list_voltage = regulator_list_voltage_table,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
static struct regulator_ops lm3632_boost_voltage_table_ops = {
.list_voltage = regulator_list_voltage_table,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
- .enable_time = lm3632_regulator_enable_time,
};
static struct regulator_desc lm3632_regulator_desc[] = {
};
static struct regulator_desc lm3632_regulator_desc[] = {
.vsel_reg = LM3632_REG_VOUT_BOOST,
.vsel_mask = LM3632_VOUT_MASK,
},
.vsel_reg = LM3632_REG_VOUT_BOOST,
.vsel_mask = LM3632_VOUT_MASK,
},
- {
- .name = "ldo_cont",
- .id = LM3632_LDO_CONT,
- .ops = &lm3632_regulator_voltage_table_ops,
- .n_voltages = ARRAY_SIZE(lm3632_ldo_cont_vtbl),
- .volt_table = lm3632_ldo_cont_vtbl,
- .type = REGULATOR_VOLTAGE,
- .owner = THIS_MODULE,
- .vsel_reg = LM3632_REG_VOUT_CONT,
- .vsel_mask = LM3632_VOUT_CONT_MASK,
- .enable_reg = LM3632_REG_LDO_CTRL2,
- .enable_mask = LM3632_EN_CONT_MASK,
- },
- {
- .name = "ldo_oref",
- .id = LM3632_LDO_OREF,
- .ops = &lm3632_regulator_voltage_table_ops,
- .n_voltages = ARRAY_SIZE(lm3632_ldo_target_vtbl),
- .volt_table = lm3632_ldo_target_vtbl,
- .type = REGULATOR_VOLTAGE,
- .owner = THIS_MODULE,
- .vsel_reg = LM3632_REG_VOUT_OREF,
- .vsel_mask = LM3632_VOUT_MASK,
- .enable_reg = LM3632_REG_LDO_CTRL1,
- .enable_mask = LM3632_EN_OREF_MASK,
- },
{
.name = "ldo_vpos",
.id = LM3632_LDO_POS,
.ops = &lm3632_regulator_voltage_table_ops,
{
.name = "ldo_vpos",
.id = LM3632_LDO_POS,
.ops = &lm3632_regulator_voltage_table_ops,
- .n_voltages = ARRAY_SIZE(lm3632_ldo_target_vtbl),
- .volt_table = lm3632_ldo_target_vtbl,
+ .n_voltages = ARRAY_SIZE(lm3632_ldo_vtbl),
+ .volt_table = lm3632_ldo_vtbl,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.vsel_reg = LM3632_REG_VOUT_POS,
.vsel_mask = LM3632_VOUT_MASK,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.vsel_reg = LM3632_REG_VOUT_POS,
.vsel_mask = LM3632_VOUT_MASK,
- .enable_reg = LM3632_REG_LDO_CTRL1,
+ .enable_reg = LM3632_REG_BIAS_CONFIG,
.enable_mask = LM3632_EN_VPOS_MASK,
},
{
.name = "ldo_vneg",
.id = LM3632_LDO_NEG,
.ops = &lm3632_regulator_voltage_table_ops,
.enable_mask = LM3632_EN_VPOS_MASK,
},
{
.name = "ldo_vneg",
.id = LM3632_LDO_NEG,
.ops = &lm3632_regulator_voltage_table_ops,
- .n_voltages = ARRAY_SIZE(lm3632_ldo_target_vtbl),
- .volt_table = lm3632_ldo_target_vtbl,
+ .n_voltages = ARRAY_SIZE(lm3632_ldo_vtbl),
+ .volt_table = lm3632_ldo_vtbl,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.vsel_reg = LM3632_REG_VOUT_NEG,
.vsel_mask = LM3632_VOUT_MASK,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.vsel_reg = LM3632_REG_VOUT_NEG,
.vsel_mask = LM3632_VOUT_MASK,
- .enable_reg = LM3632_REG_LDO_CTRL1,
+ .enable_reg = LM3632_REG_BIAS_CONFIG,
.enable_mask = LM3632_EN_VNEG_MASK,
},
};
static struct of_regulator_match lm3632_regulator_matches[] = {
{ .name = "vboost", .driver_data = (void *)LM3632_REGULATOR_BOOST, },
.enable_mask = LM3632_EN_VNEG_MASK,
},
};
static struct of_regulator_match lm3632_regulator_matches[] = {
{ .name = "vboost", .driver_data = (void *)LM3632_REGULATOR_BOOST, },
- { .name = "vcont", .driver_data = (void *)LM3632_LDO_CONT, },
- { .name = "voref", .driver_data = (void *)LM3632_LDO_OREF, },
{ .name = "vpos", .driver_data = (void *)LM3632_LDO_POS, },
{ .name = "vneg", .driver_data = (void *)LM3632_LDO_NEG, },
};
{ .name = "vpos", .driver_data = (void *)LM3632_LDO_POS, },
{ .name = "vneg", .driver_data = (void *)LM3632_LDO_NEG, },
};
{
struct device_node *node = dev->of_node;
int count;
{
struct device_node *node = dev->of_node;
int count;
+ int gpio;
count = of_regulator_match(dev, node, &lm3632_regulator_matches[id], 1);
if (count <= 0)
count = of_regulator_match(dev, node, &lm3632_regulator_matches[id], 1);
if (count <= 0)
lm3632_regulator->init_data = lm3632_regulator_matches[id].init_data;
lm3632_regulator->init_data = lm3632_regulator_matches[id].init_data;
+ /*
+ * Check LCM_EN1/2_GPIO is configured.
+ * Those pins are used for enabling VPOS/VNEG LDOs.
+ */
+ if (id == LM3632_LDO_POS) {
+ gpio = of_get_named_gpio(node, "ti,lcm-en1-gpio", 0);
+ if (gpio > 0)
+ lm3632_regulator->ena_gpio = gpio;
+ } else if (id == LM3632_LDO_NEG) {
+ gpio = of_get_named_gpio(node, "ti,lcm-en2-gpio", 0);
+ if (gpio > 0)
+ lm3632_regulator->ena_gpio = gpio;
+ }
+
return 0;
}
return 0;
}
if (!lm3632_regulator)
return -ENOMEM;
if (!lm3632_regulator)
return -ENOMEM;
+ lm3632_regulator->ena_gpio = 0;
lm3632_regulator->lm3632 = lm3632;
lm3632_regulator->lm3632 = lm3632;
-
lm3632_regulator->init_data = lm3632->pdata->regulator_data[id];
if (!lm3632_regulator->init_data) {
if (IS_ENABLED(CONFIG_OF))
lm3632_regulator->init_data = lm3632->pdata->regulator_data[id];
if (!lm3632_regulator->init_data) {
if (IS_ENABLED(CONFIG_OF))
cfg.driver_data = lm3632_regulator;
cfg.regmap = lm3632->regmap;
cfg.driver_data = lm3632_regulator;
cfg.regmap = lm3632->regmap;
+ /* Update register value if external enable pin is used */
+ if (lm3632_regulator->ena_gpio > 0) {
+ cfg.ena_gpio = lm3632_regulator->ena_gpio;
+ cfg.ena_gpio_flags = GPIOF_OUT_INIT_LOW;
+
+ ret = lm3632_update_bits(lm3632_regulator->lm3632,
+ LM3632_REG_BIAS_CONFIG,
+ LM3632_EXT_EN_MASK,
+ LM3632_EXT_EN_MASK);
+ if (ret) {
+ dev_err(&pdev->dev, "external pin err: %d\n", ret);
+ return ret;
+ }
+ }
+
rdev = regulator_register(&lm3632_regulator_desc[id], &cfg);
if (IS_ERR(rdev)) {
ret = PTR_ERR(rdev);
dev_err(&pdev->dev, "[%d] regulator register err: %d\n",
rdev = regulator_register(&lm3632_regulator_desc[id], &cfg);
if (IS_ERR(rdev)) {
ret = PTR_ERR(rdev);
dev_err(&pdev->dev, "[%d] regulator register err: %d\n",
- id + 1, ret);
+ id, ret);
return ret;
}
return ret;
}
index 0459bf179bdabfc35788a7b25debbbcfdeb6d32e..0a69737de88e74ee2e1a55b14fea6aad69001e93 100644 (file)
struct pwm_device *pwm;
};
struct pwm_device *pwm;
};
+static int lm3632_bl_string_configure(struct lm3632_bl *lm3632_bl, int enable)
+{
+ u8 val;
+
+ if (enable) {
+ if (lm3632_bl->pdata->is_full_strings)
+ val = LM3632_BL_TWO_STRINGS;
+ else
+ val = LM3632_BL_ONE_STRING;
+ } else {
+ val = 0;
+ }
+
+ return lm3632_update_bits(lm3632_bl->lm3632, LM3632_REG_ENABLE,
+ LM3632_BL_STRING_MASK, val);
+}
+
static int lm3632_bl_enable(struct lm3632_bl *lm3632_bl, int enable)
{
static int lm3632_bl_enable(struct lm3632_bl *lm3632_bl, int enable)
{
- return lm3632_update_bits(lm3632_bl->lm3632, LM3632_REG_DEVCTRL,
- LM3632_BL_EN_MASK,
- enable << LM3632_BL_EN_SHIFT);
+ int ret;
+
+ ret = lm3632_bl_string_configure(lm3632_bl, enable);
+ if (ret) {
+ dev_err(lm3632_bl->dev,
+ "Backlight string config error: %d\n", ret);
+ return ret;
+ }
+
+ return lm3632_update_bits(lm3632_bl->lm3632, LM3632_REG_ENABLE,
+ LM3632_BL_EN_MASK, enable << LM3632_BL_EN_SHIFT);
}
static void lm3632_bl_pwm_ctrl(struct lm3632_bl *lm3632_bl, int br, int max_br)
}
static void lm3632_bl_pwm_ctrl(struct lm3632_bl *lm3632_bl, int br, int max_br)
@@ -77,11 +102,12 @@ static void lm3632_bl_pwm_ctrl(struct lm3632_bl *lm3632_bl, int br, int max_br)
pwm_disable(lm3632_bl->pwm);
}
pwm_disable(lm3632_bl->pwm);
}
-static inline int lm3632_bl_set_brightness(struct lm3632_bl *lm3632_bl, int val)
+static int lm3632_bl_set_brightness(struct lm3632_bl *lm3632_bl, int val)
{
u8 data;
int ret;
{
u8 data;
int ret;
+
data = val & LM3632_BRT_LSB_MASK;
ret = lm3632_update_bits(lm3632_bl->lm3632, LM3632_REG_BRT_LSB,
LM3632_BRT_LSB_MASK, data);
data = val & LM3632_BRT_LSB_MASK;
ret = lm3632_update_bits(lm3632_bl->lm3632, LM3632_REG_BRT_LSB,
LM3632_BRT_LSB_MASK, data);
return ret;
data = (val >> LM3632_BRT_MSB_SHIFT) & 0xFF;
return ret;
data = (val >> LM3632_BRT_MSB_SHIFT) & 0xFF;
+
return lm3632_write_byte(lm3632_bl->lm3632, LM3632_REG_BRT_MSB,
data);
}
return lm3632_write_byte(lm3632_bl->lm3632, LM3632_REG_BRT_MSB,
data);
}
char name[20];
props.type = BACKLIGHT_PLATFORM;
char name[20];
props.type = BACKLIGHT_PLATFORM;
- props.brightness = pdata ? pdata->init_brightness : 0;
+ props.brightness = 0;
props.max_brightness = LM3632_MAX_BRIGHTNESS;
if (!pdata || !pdata->name)
props.max_brightness = LM3632_MAX_BRIGHTNESS;
if (!pdata || !pdata->name)
backlight_device_unregister(lm3632_bl->bl_dev);
}
backlight_device_unregister(lm3632_bl->bl_dev);
}
-static int lm3632_bl_set_ctrl_mode(struct lm3632_bl *lm3632_bl)
+static int lm3632_bl_set_ovp(struct lm3632_bl *lm3632_bl)
{
{
- struct lm3632_backlight_platform_data *pdata = lm3632_bl->pdata;
-
- /* Brightness control mode is I2C only by default */
- if (!pdata) {
- lm3632_bl->mode = LMU_BL_I2C;
- return lm3632_update_bits(lm3632_bl->lm3632,
- LM3632_REG_BRT_MODE, LM3632_BRT_MASK,
- LM3632_I2C_ONLY);
- }
-
- if (pdata->pwm_period > 0)
- lm3632_bl->mode = LMU_BL_PWM;
+ return lm3632_update_bits(lm3632_bl->lm3632, LM3632_REG_CONFIG1,
+ LM3632_OVP_MASK, LM3632_OVP_25V);
+}
- return lm3632_update_bits(lm3632_bl->lm3632, LM3632_REG_BRT_MODE,
- LM3632_BRT_MASK, pdata->mode);
+static int lm3632_bl_set_swfreq(struct lm3632_bl *lm3632_bl)
+{
+ return lm3632_update_bits(lm3632_bl->lm3632, LM3632_REG_CONFIG2,
+ LM3632_SWFREQ_MASK, LM3632_SWFREQ_1MHZ);
}
}
-static int lm3632_bl_string_configure(struct lm3632_bl *lm3632_bl)
+static int lm3632_bl_set_ctrl_mode(struct lm3632_bl *lm3632_bl)
{
{
- u8 val;
+ struct lm3632_backlight_platform_data *pdata = lm3632_bl->pdata;
- if (lm3632_bl->pdata->is_full_strings)
- val = LM3632_BL_TWO_STRINGS;
+ if (pdata->pwm_period > 0)
+ lm3632_bl->mode = LMU_BL_PWM;
else
else
- val = LM3632_BL_ONE_STRING;
+ lm3632_bl->mode = LMU_BL_I2C;
- return lm3632_update_bits(lm3632_bl->lm3632, LM3632_REG_BL_CFG,
- LM3632_BL_STRING_MASK, val);
+ return lm3632_update_bits(lm3632_bl->lm3632, LM3632_REG_IO_CTRL,
+ LM3632_PWM_MASK,
+ lm3632_bl->mode << LM3632_PWM_SHIFT);
}
static int lm3632_bl_configure(struct lm3632_bl *lm3632_bl)
{
int ret;
}
static int lm3632_bl_configure(struct lm3632_bl *lm3632_bl)
{
int ret;
- ret = lm3632_bl_set_ctrl_mode(lm3632_bl);
+ /* Select OVP level */
+ ret = lm3632_bl_set_ovp(lm3632_bl);
+ if (ret)
+ return ret;
+
+ /* Select switch frequency */
+ ret = lm3632_bl_set_swfreq(lm3632_bl);
if (ret)
return ret;
if (ret)
return ret;
- return lm3632_bl_string_configure(lm3632_bl);
+ /* Backlight control mode - PWM or I2C */
+ return lm3632_bl_set_ctrl_mode(lm3632_bl);
}
static int lm3632_bl_parse_dt(struct device *dev, struct lm3632_bl *lm3632_bl)
{
struct device_node *node = dev->of_node;
struct lm3632_backlight_platform_data *pdata;
}
static int lm3632_bl_parse_dt(struct device *dev, struct lm3632_bl *lm3632_bl)
{
struct device_node *node = dev->of_node;
struct lm3632_backlight_platform_data *pdata;
+ int brightness = 0;
+ int ret;
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return -ENOMEM;
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return -ENOMEM;
+ /* Channel name */
of_property_read_string(node, "bl-name", &pdata->name);
of_property_read_string(node, "bl-name", &pdata->name);
+ /* String configuration */
if (of_find_property(node, "full-strings-used", NULL))
pdata->is_full_strings = true;
if (of_find_property(node, "full-strings-used", NULL))
pdata->is_full_strings = true;
- if (of_find_property(node, "mode-pwm-only", NULL))
- pdata->mode = LM3632_PWM_ONLY;
- else if (of_find_property(node, "mode-comb1", NULL))
- pdata->mode = LM3632_COMB1;
- else if (of_find_property(node, "mode-comb2", NULL))
- pdata->mode = LM3632_COMB2;
+ /* PWM mode */
+ of_property_read_u32(node, "pwm-period", &pdata->pwm_period);
+ of_property_read_u32(node, "pwm-max-brightness", &brightness);
- of_property_read_u8(node, "initial-brightness",
- (u8 *)&pdata->init_brightness);
+ if (pdata->pwm_period > 0) {
+ if (brightness == 0) {
+ dev_err(lm3632_bl->dev,
+ "PWM max brightness should be greater than 0\n");
+ return -EINVAL;
+ }
- of_property_read_u32(node, "pwm-period", &pdata->pwm_period);
+ ret = lm3632_bl_set_brightness(lm3632_bl, brightness);
+ if (ret) {
+ dev_err(lm3632_bl->dev,
+ "PWM max brightness set error: %d\n", ret);
+ return ret;
+ }
+ }
lm3632_bl->pdata = pdata;
lm3632_bl->pdata = pdata;
if (!lm3632_bl)
return -ENOMEM;
if (!lm3632_bl)
return -ENOMEM;
+ lm3632_bl->dev = &pdev->dev;
+ lm3632_bl->lm3632 = lm3632;
lm3632_bl->pdata = pdata;
lm3632_bl->pdata = pdata;
+
if (!lm3632_bl->pdata) {
if (IS_ENABLED(CONFIG_OF))
ret = lm3632_bl_parse_dt(&pdev->dev, lm3632_bl);
if (!lm3632_bl->pdata) {
if (IS_ENABLED(CONFIG_OF))
ret = lm3632_bl_parse_dt(&pdev->dev, lm3632_bl);
return ret;
}
return ret;
}
- lm3632_bl->dev = &pdev->dev;
- lm3632_bl->lm3632 = lm3632;
platform_set_drvdata(pdev, lm3632_bl);
platform_set_drvdata(pdev, lm3632_bl);
+ /* Backlight configuration */
ret = lm3632_bl_configure(lm3632_bl);
if (ret) {
dev_err(&pdev->dev, "backlight config err: %d\n", ret);
return ret;
}
ret = lm3632_bl_configure(lm3632_bl);
if (ret) {
dev_err(&pdev->dev, "backlight config err: %d\n", ret);
return ret;
}
+ /* Register backlight subsystem */
ret = lm3632_bl_register(lm3632_bl);
if (ret) {
dev_err(&pdev->dev, "register backlight err: %d\n", ret);
ret = lm3632_bl_register(lm3632_bl);
if (ret) {
dev_err(&pdev->dev, "register backlight err: %d\n", ret);
index 84701481eead4df5318139742d198a6dd95ecc9b..bd973c6922971cd0b1550c2e3d1b534a88314183 100644 (file)
/*
/*
- * TI LM3631 MFD Driver
+ * TI LM3632 MFD Driver
*
*
- * Copyright 2013 Texas Instruments
+ * Copyright 2015 Texas Instruments
*
* Author: Milo Kim <milo.kim@ti.com>
*
*
* Author: Milo Kim <milo.kim@ti.com>
*
*
*/
*
*/
-#ifndef __MFD_LM3631_H__
-#define __MFD_LM3631_H__
+#ifndef __MFD_LM3632_H__
+#define __MFD_LM3632_H__
#include <linux/gpio.h>
#include <linux/pwm.h>
#include <linux/gpio.h>
#include <linux/pwm.h>
#include <linux/regulator/machine.h>
/* Registers */
#include <linux/regulator/machine.h>
/* Registers */
-#define LM3631_REG_DEVCTRL 0x00
-#define LM3631_LCD_EN_MASK BIT(1)
-#define LM3631_LCD_EN_SHIFT 1
-#define LM3631_BL_EN_MASK BIT(0)
-#define LM3631_BL_EN_SHIFT 0
-
-#define LM3631_REG_BRT_LSB 0x01
-#define LM3631_BRT_LSB_MASK (BIT(0) | BIT(1) | BIT(2))
-#define LM3631_REG_BRT_MSB 0x02
-#define LM3631_BRT_MSB_SHIFT 3
-
-#define LM3631_REG_BL_CFG 0x06
-#define LM3631_BL_STRING_MASK BIT(3)
-#define LM3631_BL_TWO_STRINGS 0
-#define LM3631_BL_ONE_STRING BIT(3)
-
-#define LM3631_REG_BRT_MODE 0x08
-#define LM3631_BRT_MASK (BIT(2) | BIT(3))
-
-#define LM3631_REG_LDO_CTRL1 0x0A
-#define LM3631_EN_OREF_MASK BIT(0)
-#define LM3631_EN_VNEG_MASK BIT(1)
-#define LM3631_EN_VPOS_MASK BIT(2)
-
-#define LM3631_REG_LDO_CTRL2 0x0B
-#define LM3631_EN_CONT_MASK BIT(0)
-
-#define LM3631_REG_VOUT_CONT 0x0C
-#define LM3631_VOUT_CONT_MASK (BIT(6) | BIT(7))
-
-#define LM3631_REG_VOUT_BOOST 0x0C
-#define LM3631_REG_VOUT_POS 0x0D
-#define LM3631_REG_VOUT_NEG 0x0E
-#define LM3631_REG_VOUT_OREF 0x0F
-#define LM3631_VOUT_MASK 0x3F
-
-#define LM3631_REG_ENTIME_VCONT 0x0B
-#define LM3631_ENTIME_CONT_MASK 0x70
-
-#define LM3631_REG_ENTIME_VOREF 0x0F
-#define LM3631_REG_ENTIME_VPOS 0x10
-#define LM3631_REG_ENTIME_VNEG 0x11
-#define LM3631_ENTIME_MASK 0xF0
-#define LM3631_ENTIME_SHIFT 4
-
-#define LM3631_MAX_REGISTERS 0x16
-
-#define LM3631_NUM_REGULATORS 5
-
-enum lm3631_brightness_mode {
- LM3631_I2C_ONLY = 0 << 2,
- LM3631_PWM_ONLY = 1 << 2,
- LM3631_COMB1 = 2 << 2, /* I2C x PWM befoer sloping */
- LM3631_COMB2 = 3 << 2, /* Sloped I2C x PWM */
-};
+#define LM3632_REG_CONFIG1 0x02
+#define LM3632_OVP_MASK (BIT(5) | BIT(6) | BIT(7))
+#define LM3632_OVP_25V BIT(6)
+
+#define LM3632_REG_CONFIG2 0x03
+#define LM3632_SWFREQ_MASK BIT(7)
+#define LM3632_SWFREQ_1MHZ BIT(7)
+
+#define LM3632_REG_BRT_LSB 0x04
+#define LM3632_BRT_LSB_MASK (BIT(0) | BIT(1) | BIT(2))
+#define LM3632_REG_BRT_MSB 0x05
+#define LM3632_BRT_MSB_SHIFT 3
+
+#define LM3632_REG_IO_CTRL 0x09
+#define LM3632_PWM_MASK BIT(6)
+#define LM3632_PWM_SHIFT 6
+
+#define LM3632_REG_ENABLE 0x0A
+#define LM3632_BL_EN_MASK BIT(0)
+#define LM3632_BL_EN_SHIFT 0
+#define LM3632_BL_STRING_MASK (BIT(3) | BIT(4))
+#define LM3632_BL_ONE_STRING BIT(4)
+#define LM3632_BL_TWO_STRINGS BIT(3)
+
+#define LM3632_REG_BIAS_CONFIG 0x0C
+#define LM3632_EXT_EN_MASK BIT(0)
+#define LM3632_EN_VNEG_MASK BIT(1)
+#define LM3632_EN_VPOS_MASK BIT(2)
+
+#define LM3632_REG_VOUT_BOOST 0x0D
+#define LM3632_REG_VOUT_POS 0x0E
+#define LM3632_REG_VOUT_NEG 0x0F
+#define LM3632_VOUT_MASK 0x3F
+
+#define LM3632_MAX_REGISTERS 0x10
+
+#define LM3632_NUM_REGULATORS 3
/*
/*
- * struct lm3633_bl_platform_data
+ * struct lm3632_backlight_platform_data
* @name: Backlight driver name
* @is_full_strings: set true if two strings are used
* @name: Backlight driver name
* @is_full_strings: set true if two strings are used
- * @init_brightness: Initial brightness value
- * @mode: Backlight control mode
* @pwm_period: Platform specific PWM period value. unit is nano
*/
* @pwm_period: Platform specific PWM period value. unit is nano
*/
-struct lm3631_backlight_platform_data {
+struct lm3632_backlight_platform_data {
const char *name;
bool is_full_strings;
const char *name;
bool is_full_strings;
- u8 init_brightness;
- enum lm3631_brightness_mode mode;
/* Only valid in case of PWM mode */
unsigned int pwm_period;
};
/*
/* Only valid in case of PWM mode */
unsigned int pwm_period;
};
/*
- * struct lmu_platform_data
- * @en_gpio: GPIO for nRST pin
+ * struct lm3632_platform_data
+ * @en_gpio: GPIO for chip enable pin
+ * @lcm_en1_gpio: GPIO for VPOS LDO
+ * @lcm_en2_gpio: GPIO for VNEG LDO
* @regulator_data: Regulator initial data for LCD bias
* @bl_pdata: Backlight platform data
*/
* @regulator_data: Regulator initial data for LCD bias
* @bl_pdata: Backlight platform data
*/
-struct lm3631_platform_data {
+struct lm3632_platform_data {
int en_gpio;
int en_gpio;
- struct regulator_init_data *regulator_data[LM3631_NUM_REGULATORS];
- struct lm3631_backlight_platform_data *bl_pdata;
+ int lcm_en1_gpio;
+ int lcm_en2_gpio;
+ struct regulator_init_data *regulator_data[LM3632_NUM_REGULATORS];
+ struct lm3632_backlight_platform_data *bl_pdata;
};
/*
};
/*
- * struct lm3631
+ * struct lm3632
* @dev: Parent device pointer
* @regmap: Used for i2c communcation on accessing registers
* @pdata: LMU platform specific data
*/
* @dev: Parent device pointer
* @regmap: Used for i2c communcation on accessing registers
* @pdata: LMU platform specific data
*/
-struct lm3631 {
+struct lm3632 {
struct device *dev;
struct regmap *regmap;
struct device *dev;
struct regmap *regmap;
- struct lm3631_platform_data *pdata;
+ struct lm3632_platform_data *pdata;
};
};
-int lm3631_read_byte(struct lm3631 *lm3631, u8 reg, u8 *read);
-int lm3631_write_byte(struct lm3631 *lm3631, u8 reg, u8 data);
-int lm3631_update_bits(struct lm3631 *lm3631, u8 reg, u8 mask, u8 data);
+int lm3632_read_byte(struct lm3632 *lm3632, u8 reg, u8 *read);
+int lm3632_write_byte(struct lm3632 *lm3632, u8 reg, u8 data);
+int lm3632_update_bits(struct lm3632 *lm3632, u8 reg, u8 mask, u8 data);
#endif
#endif