#include "devices.h"
#include "../../../drivers/spi/rk2818_spim.h"
-
+#include "../../../drivers/regulator/rk2818_lp8725.h"
/* --------------------------------------------------------------------
* ÉùÃ÷ÁËrk2818_gpioBankÊý×飬²¢¶¨ÒåÁËGPIO¼Ä´æÆ÷×éIDºÍ¼Ä´æÆ÷»ùµØÖ·¡£
* -------------------------------------------------------------------- */
};
#endif
+/*****************************************************************************************
+ *regulator devices drivers/regulator/rk2818_lp8725.c linux/regulator/rk2818_lp8725.h
+ *author: cym
+*****************************************************************************************/
+#if defined (CONFIG_RK2818_REGULATOR_LP8725)
+/*ldo1 2V8OUT USB2.5V LCD_VCC*/
+static struct regulator_consumer_supply ldo1_consumers[] = {
+ {
+ .supply = "ldo1",
+ }
+};
+
+static struct regulator_init_data rk2818_lp8725_ldo1_data = {
+ .constraints = {
+ .name = "LDO1",
+ .min_uV = 1200000,
+ .max_uV = 3300000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ldo1_consumers),
+ .consumer_supplies = ldo1_consumers,
+};
+
+/*ldo2 CAMERA_1V8 SD_CARD*/
+static struct regulator_consumer_supply ldo2_consumers[] = {
+ {
+ .supply = "ldo2",
+ }
+};
+
+static struct regulator_init_data rk2818_lp8725_ldo2_data = {
+ .constraints = {
+ .name = "LDO2",
+ .min_uV = 1200000,
+ .max_uV = 3300000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ldo2_consumers),
+ .consumer_supplies = ldo2_consumers,
+};
+
+/*ldo3 VCC_NAND WIFI/BT/FM_BCM4325*/
+static struct regulator_consumer_supply ldo3_consumers[] = {
+ {
+ .supply = "ldo3",
+ }
+};
+
+static struct regulator_init_data rk2818_lp8725_ldo3_data = {
+ .constraints = {
+ .name = "LDO3",
+ .min_uV = 1200000,
+ .max_uV = 3300000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ldo3_consumers),
+ .consumer_supplies = ldo3_consumers,
+};
+
+/*ldo4 VCCA CODEC_WM8994*/
+static struct regulator_consumer_supply ldo4_consumers[] = {
+ {
+ .supply = "ldo4",
+ }
+};
+
+static struct regulator_init_data rk2818_lp8725_ldo4_data = {
+ .constraints = {
+ .name = "LDO4",
+ .min_uV = 1200000,
+ .max_uV = 3300000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ldo4_consumers),
+ .consumer_supplies = ldo4_consumers,
+};
+
+/*ldo5 AVDD18 CODEC_WM8994*/
+static struct regulator_consumer_supply ldo5_consumers[] = {
+ {
+ .supply = "ldo5",
+ }
+};
+
+static struct regulator_init_data rk2818_lp8725_ldo5_data = {
+ .constraints = {
+ .name = "LDO5",
+ .min_uV = 1200000,
+ .max_uV = 3300000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ldo5_consumers),
+ .consumer_supplies = ldo5_consumers,
+};
+
+/*lilo1 VCCIO Sensor£¨3M£©*/
+static struct regulator_consumer_supply lilo1_consumers[] = {
+ {
+ .supply = "lilo1",
+ }
+};
+
+static struct regulator_init_data rk2818_lp8725_lilo1_data = {
+ .constraints = {
+ .name = "LILO1",
+ .min_uV = 800000,
+ .max_uV = 3300000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(lilo1_consumers),
+ .consumer_supplies = lilo1_consumers
+};
+
+/*lilo2 VCC33_SD Sensor£¨3M£©*/
+static struct regulator_consumer_supply lilo2_consumers[] = {
+ {
+ .supply = "lilo2",
+ }
+};
+
+static struct regulator_init_data rk2818_lp8725_lilo2_data = {
+ .constraints = {
+ .name = "LILO2",
+ .min_uV = 800000,
+ .max_uV = 3300000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(lilo2_consumers),
+ .consumer_supplies = lilo2_consumers
+};
+
+/*buck1 VDD12 Core*/
+static struct regulator_consumer_supply buck1_consumers[] = {
+ {
+ .supply = "vdd12",
+ }
+};
+
+static struct regulator_init_data rk2818_lp8725_buck1_data = {
+ .constraints = {
+ .name = "VDD12",
+ .min_uV = 800000,
+ .max_uV = 1500000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(buck1_consumers),
+ .consumer_supplies = buck1_consumers
+};
+
+/*buck2 VDDDR MobileDDR VCC*/
+static struct regulator_consumer_supply buck2_consumers[] = {
+ {
+ .supply = "vccdr",
+ }
+};
+
+static struct regulator_init_data rk2818_lp8725_buck2_data = {
+ .constraints = {
+ .name = "VCCDR",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(buck2_consumers),
+ .consumer_supplies = buck2_consumers
+};
+
+
+
+
+struct lp8725_regulator_subdev rk2818_lp8725_regulator_subdev[] = {
+ {
+ .id=LP8725_LDO1,
+ .initdata=&rk2818_lp8725_ldo1_data,
+ },
+
+ {
+ .id=LP8725_LDO2,
+ .initdata=&rk2818_lp8725_ldo2_data,
+ },
+
+ {
+ .id=LP8725_LDO3,
+ .initdata=&rk2818_lp8725_ldo3_data,
+ },
+
+ {
+ .id=LP8725_LDO4,
+ .initdata=&rk2818_lp8725_ldo4_data,
+ },
+
+ {
+ .id=LP8725_LDO5,
+ .initdata=&rk2818_lp8725_ldo5_data,
+ },
+
+ {
+ .id=LP8725_LILO1,
+ .initdata=&rk2818_lp8725_lilo1_data,
+ },
+
+ {
+ .id=LP8725_LILO2,
+ .initdata=&rk2818_lp8725_lilo2_data,
+ },
+
+ {
+ .id=LP8725_DCDC1,
+ .initdata=&rk2818_lp8725_buck1_data,
+ },
+
+ {
+ .id=LP8725_DCDC2,
+ .initdata=&rk2818_lp8725_buck2_data,
+ },
+
+};
+
+struct lp8725_platform_data rk2818_lp8725_data={
+ .num_regulators=LP8725_NUM_REGULATORS,
+ .regulators=rk2818_lp8725_regulator_subdev,
+};
+#endif
+
/*****************************************************************************************
* I2C devices
*author: kfx
.platform_data=&rk2818_pca9554_data.gpio_base,
},
#endif
-#if defined (CONFIG_PMIC_LP8725)
+#if defined (CONFIG_RK2818_REGULATOR_LP8725)
{
.type = "lp8725",
.addr = 0x79,
.flags = 0,
+ .platform_data=&rk2818_lp8725_data,
},
#endif
#if defined (CONFIG_GS_MMA7660)
depends on RK28_ADC
help
Say Y to enable support for the battery on the RK2818.
-
-config PMIC_LP8725
-tristate "pmic lp8725"
-depends on I2C
-help
- Say Y to enable support for the pmic lp8725 on the RK2818.
endif # POWER_SUPPLY
obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o
obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o
obj-$(CONFIG_BATTERY_RK2818) += rk2818_battery.o
-obj-$(CONFIG_PMIC_LP8725) += pmic_lp8725.o
+++ /dev/null
-/* arch/arm/mach-rk2818/example.c
- *
- * Copyright (C) 2010 ROCKCHIP, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-/*******************************************************************/
-/* COPYRIGHT (C) ROCK-CHIPS FUZHOU . ALL RIGHTS RESERVED. */
-/*******************************************************************
-FILE : PCA9554.C
-DESC : À©Õ¹GPIO µÄÇý¶¯Ïà¹Ø³ÌÐò
-AUTHOR : ZHONGYW
-DATE : 2009-4-26
-NOTES :
-$LOG: GPIO.C,V $
-REVISION 0.01
-********************************************************************/
-#include <linux/clk.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <asm/mach-types.h>
-#include <linux/irq.h>
-#include <linux/debugfs.h>
-#include <linux/seq_file.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/io.h>
-#include <mach/hardware.h>
-#include <mach/gpio.h>
-#include <mach/rk2818_iomap.h>
-#include <mach/iomux.h>
-#include <linux/device.h>
-#include <mach/gpio.h>
-#include <asm/gpio.h>
-#include <linux/i2c.h>
-#include <linux/workqueue.h>
-#include <mach/board.h>
-#include <linux/delay.h>
-
-
-#if 1
-#define DBG(x...) printk(KERN_INFO x)
-#else
-#define DBG(x...)
-#endif
-
-#if 1
-#define DBGERR(x...) printk(KERN_INFO x)
-#else
-#define DBGERR(x...)
-#endif
-
-#define DEFSEL_VIN1
-
-#define GENERAL_REG_ADDR 0x0
-#define LDO1_REG_ADDR 0x01
-#define LDO2_REG_ADDR 0x02
-#define LDO3_REG_ADDR 0x03
-#define LDO4_REG_ADDR 0x04
-#define LDO5_REG_ADDR 0x05
-#define LILO1_REG_ADDR 0x06
-#define LILO2_REG_ADDR 0x07
-#define BUCK1_V1_REG_ADDR 0x08
-#define BUCK1_V2_REG_ADDR 0x09
-#define BUCK2_V1_REG_ADDR 0x0a
-#define BUCK2_V2_REG_ADDR 0x0b
-#define BUCK_CTR_REG_ADDR 0x0c
-#define LDO_CTR_REG_ADDR 0x0d
-#define PULLDOWN_REG_ADDR 0x0e
-#define STATUS_REG_ADDR 0x0f
-
-#define LP8725_LDO_NUM 5
-#define LP8725_LILO_NUM 2
-#define LP8725_BUCK_NUM 2
-
-
-#define LDO_BUCKV1_TIME 5 //¸ß3
-#define LDO_BUCKV_V 0 //µÚ5
-#define BUCKV2_CL_BIT 6 //¸ß2
-
-#ifdef DEFSEL_VIN1
-#define GENERAL_REG_DEFAULT 0x59 //0101 1001 buck1output dependon dvs pin, dvs=1 v1 is used buck2v1 is output
-
-#define LDO1_REG_T_DEFAULT 0x02 //1001 1001
-#define LDO1_REG_V_DEFAULT 0x19
-#define LDO2_REG_T_DEFAULT 0x04 //1001 1001
-#define LDO2_REG_V_DEFAULT 0x19
-#define LDO3_REG_T_DEFAULT 0x05 // 1011 1111
-#define LDO3_REG_V_DEFAULT 0x1f
-#define LDO4_REG_T_DEFAULT 0x04 // 1001 1101
-#define LDO4_REG_V_DEFAULT 0x1d
-#define LDO5_REG_T_DEFAULT 0x04 //1000 1100
-#define LDO5_REG_V_DEFAULT 0x0c
-
-#define LILO1_REG_T_DEFAULT 0x05 //1010 1000
-#define LILO1_REG_V_DEFAULT 0x08
-#define LILO2_REG_T_DEFAULT 0x02 // 0101 0000
-#define LILO2_REG_V_DEFAULT 0x10
-
-#define BUCK1_V1_REG_T_DEFAULT 0x00 // 0000 0100
-#define BUCK1_V1_REG_V_DEFAULT 0x04
-
-#define BUCK1_V2_REG_C_DEFAULT 0x03 //1100 1000 ¸ß¶þ
-#define BUCK1_V2_REG_V_DEFAULT 0x08
-
-#define BUCK2_V1_REG_T_DEFAULT 0x02 // 0101 0001
-#define BUCK2_V1_REG_V_DEFAULT 0x11
-
-#define BUCK2_V2_REG_C_DEFAULT 0x02//1001 0001 ¸ß¶þ
-#define BUCK2_V2_REG_V_DEFAULT 0x11// µÚ5
-
-#define BUCK2_CTR_REG_ADDR 0x11 // 0001 0001
-#define LDO_CTR_REG_DEFAULT 0x7f //0111 1111
-#define PULLDOWN_DEFAULT 0x7f //0111 1111
-#define STATUS_REG_DEFAULT 0x00 //0000 0000
-
-#else
-
-
-
-#define GENERAL_REG_DEFAULT 0x59 //0101 1001
-
-#define LDO1_REG_T_DEFAULT 0x01 // 0011 0101
-#define LDO1_REG_V_DEFAULT 0x15
-#define LDO2_REG_T_DEFAULT 0x01 // 0011 1001
-#define LDO2_REG_V_DEFAULT 0x19
-
-#define LDO3_REG_T_DEFAULT 0x02 // 0101 1001
-#define LDO3_REG_V_DEFAULT 0x19
-#define LDO4_REG_T_DEFAULT 0x02 // 0101 1001
-#define LDO4_REG_V_DEFAULT 0x19
-#define LDO5_REG_T_DEFAULT 0x01 // 0011 1001
-#define LDO5_REG_V_DEFAULT 0x19
-
-#define LILO1_REG_T_DEFAULT 0x01 //0011 1111
-#define LILO1_REG_V_DEFAULT 0x1f
-
-#define LILO2_REG_T_DEFAULT 0x00 // 0000 1000
-#define LILO2_REG_V_DEFAULT 0x08
-
-#define BUCK1_V1_REG_T_DEFAULT 0x00 // 0000 1000
-#define BUCK1_V1_REG_V_DEFAULT 0x08
-
-#define BUCK1_V2_REG_C_DEFAULT 0x03 //1100 0100 ¸ß¶þ
-#define BUCK1_V2_REG_V_DEFAULT 0x04
-
-#define BUCK2_V1_REG_T_DEFAULT 0x01 // 0011 0001
-#define BUCK2_V1_REG_V_DEFAULT 0x11
-
-#define BUCK2_V2_REG_C_DEFAULT 0x02 //1001 0001 ¸ß¶þ
-#define BUCK2_V2_REG_V_DEFAULT 0x11// µÚ5
-
-#define BUCK_CTR_REG_ADDR 0x11 // 0001 0001
-#define LDO_CTR_REG_DEFAULT 0x7f //0111 1111
-#define PULLDOWN_REG_DEFAULT 0x7f //0111 1111
-#define STATUS_REG_DEFAULT 0x00 //0000 0000
-#endif
-
-
-struct i2c_client *lp8725_client;
-#define lp8725getbit(a,num) (((a)>>(num))&0x01)
-#define lp8725setbit(a,num) ((a)|(0x01<<(num)))
-#define lp8725clearbit(a,num) ((a)&(~(0x01<<(num))))
-
-
-static const struct i2c_device_id lp8725_id[] =
-{
- { "lp8725", 0, },
- { }
-};
-
-MODULE_DEVICE_TABLE(i2c, lp8725_id);
-
-struct lp8725_regs_s
-{
-uint8_t general_reg_val;
-uint8_t ldo_reg_val[5];
-uint8_t lilo_reg_val[2];
-uint8_t buck_v1_reg_val[2];
-uint8_t buck_v2_reg_val[2];
-uint8_t buck_ctr_reg_val;
-uint8_t ldo_ctr_reg_val;
-uint8_t pulldown_reg_val;
-uint8_t status_reg_val;
-};
-struct lp8725_vol_range_s
-{
- uint16_t vol_low;
- uint16_t vol_high;
- uint16_t rang;
-};
-
-
-static struct lp8725_regs_s lp8725_regs;
-
-
-uint8_t ldo_reg_t_default[LP8725_LDO_NUM]={LDO1_REG_T_DEFAULT,LDO2_REG_T_DEFAULT,LDO3_REG_T_DEFAULT,LDO4_REG_T_DEFAULT,LDO5_REG_T_DEFAULT};
-uint8_t ldo_reg_v_default[LP8725_LDO_NUM]={LDO1_REG_V_DEFAULT,LDO2_REG_V_DEFAULT,LDO3_REG_V_DEFAULT,LDO4_REG_V_DEFAULT,LDO5_REG_V_DEFAULT};
-
-uint8_t lilo_reg_t_default[LP8725_LILO_NUM]={LILO1_REG_T_DEFAULT,LILO2_REG_T_DEFAULT};
-uint8_t lilo_reg_v_default[LP8725_LILO_NUM]={LILO1_REG_V_DEFAULT,LILO2_REG_V_DEFAULT};
-
-uint8_t buck_v1_reg_t_default[LP8725_BUCK_NUM]={BUCK1_V1_REG_T_DEFAULT,BUCK2_V1_REG_T_DEFAULT};
-uint8_t buck_v1_reg_v_default[LP8725_BUCK_NUM]={BUCK1_V1_REG_V_DEFAULT,BUCK2_V1_REG_V_DEFAULT};
-
-uint8_t buck_v2_reg_c_default[LP8725_BUCK_NUM]={BUCK1_V2_REG_C_DEFAULT,BUCK2_V2_REG_C_DEFAULT};
-uint8_t buck_v2_reg_v_default[LP8725_BUCK_NUM]={BUCK1_V2_REG_V_DEFAULT,BUCK2_V2_REG_V_DEFAULT};
-
-
-#define LDO_RANG 5
-#define LILO_RANG 5
-#define BULK_RANG 6
-
-struct lp8725_vol_range_s ldo_vol_range[LDO_RANG]={{120,190,5},{190,260,10},{260,300,5},{300,310,10},{310,330,20}};
-struct lp8725_vol_range_s lilo_vol_range[LILO_RANG]={{80,140,5},{140,280,10},{280,290,5},{290,310,10},{310,330,20}};
-struct lp8725_vol_range_s buck_vol_range[BULK_RANG]={{80,140,5},{140,170,10},{170,190,5},{190,280,10},{280,290,5},{290,300,10}};
-/* **********************************************************************
- * д¼Ä´æÆ÷
- * return <0 failed
- * * ***********************************************************************/
-static int lp8725_write_reg(struct i2c_client *client, uint8_t reg, uint8_t val)
-{
- int ret=-1;
- DBG("**run in %s**\n",__FUNCTION__);
- struct i2c_adapter *adap;
- struct i2c_msg msg;
- char tx_buf[2];
- if(!client)
- return ret;
- adap = client->adapter;
- tx_buf[0] = reg;
- tx_buf[1]=val;
- //DBG("**run in %s**\n",__FUNCTION__);
-
- msg.addr = client->addr;
- msg.buf = &tx_buf[0];
- msg.len = 1 +1;
- msg.flags = client->flags;
- msg.scl_rate = 200*1000;
- //DBG("**run in %s**\n",__FUNCTION__);
-
- ret = i2c_transfer(adap, &msg, 1);
- //DBG("**run in %s**\n",__FUNCTION__);
- return ret;
- DBG("**run out %s**\n",__FUNCTION__);
-}
-/* **********************************************************************
- * ¶Á¼Ä´æÆ÷
- * return <0 failed
- * * ***********************************************************************/
- #if 1
-static int lp8725_read_reg(struct i2c_client *client, uint8_t reg, uint8_t *val)
-{
-
- int ret;
- struct i2c_adapter *adap;
- struct i2c_msg msgs[2];
- if(!client)
- return ret;
- adap = client->adapter;
- //·¢ËͼĴæÆ÷µØÖ·
- msgs[0].addr = client->addr;
- msgs[0].buf = ®
- msgs[0].flags = client->flags;
- msgs[0].len = 1;
- msgs[0].scl_rate = 200*1000;
- //½ÓÊÕÊý¾Ý
- //msgs[1].buf = val;
- DBG("msgs[1].buf = %d\n",*msgs[1].buf);
- //msgs[1].buf = val;
- msgs[1].buf = val;
- msgs[1].addr = client->addr;
- msgs[1].flags = client->flags | I2C_M_RD;
- msgs[1].len = 1;
- msgs[1].scl_rate = 200*1000;
-
- ret = i2c_transfer(adap, msgs, 2);
- //DBG("**has run at %s %d ret=%d**\n",__FUNCTION__,__LINE__,ret);
- DBG("msgs[1].buf = %d\n",*(msgs[1].buf));
-
- return ret;
-}
-#else
-static int lp8725_read_reg(struct i2c_client *client, uint8_t reg)
-{
-
- int ret;
- struct i2c_adapter *adap;
- struct i2c_msg msgs[2];
- if(!client)
- return ret;
- adap = client->adapter;
- //·¢ËͼĴæÆ÷µØÖ·
- msgs[0].addr = client->addr;
- msgs[0].buf = ®
- msgs[0].flags = client->flags;
- msgs[0].len = 1;
- msgs[0].scl_rate = 200*1000;
- //½ÓÊÕÊý¾Ý
- msgs[1].buf;
- msgs[1].addr = client->addr;
- msgs[1].flags = client->flags | I2C_M_RD;
- msgs[1].len = 1;
- msgs[1].scl_rate = 200*1000;
-
- ret = i2c_transfer(adap, msgs, 2);
- //DBG("**has run at %s %d ret=%d**\n",__FUNCTION__,__LINE__,ret);
- DBG("msgs[1].buf = %d\n",*msgs[1].buf);
- return ret;
-}
-#endif
-/* **********************************************************************
- * ÉèÖÃldoµÄÊä³öµçѹ
- *ldon:ldo±àºÅ Èçldo1 ldon=1£¬vol µçѹµ¥Î»10mv Èç1.2v vol=120
- *µçѹ·¶Î§:´Ó1.2v¿ªÊ¼²½½ø0.05v
- * return <0 failed
- * * ***********************************************************************/
-int lp8725_set_ldo_vol(uint8_t ldon,uint16_t vol)
-{
-
- uint8_t val=0;
- uint8_t reg_val=0;
- int i;
-
- if((vol>ldo_vol_range[LDO_RANG-1].vol_high)||(vol<ldo_vol_range[0].vol_low)||ldon>LP8725_LDO_NUM)
- return -1;
-
- for(i=0;i<LDO_RANG;i++)
- {
- if(vol<=ldo_vol_range[i].vol_high)
- {
- val+=(vol-ldo_vol_range[i].vol_low)/ldo_vol_range[i].rang;
- break;
- }
- else
- val+=(ldo_vol_range[i].vol_high-ldo_vol_range[i].vol_low)/ldo_vol_range[i].rang;
- DBG("val=0x%x,vol=%d\n",val,vol);
- }
-
- DBG("val=0x%x,vol=%d\n",val,vol);
-
- reg_val=(ldo_reg_t_default[ldon-1]<<LDO_BUCKV1_TIME)|val;
- DBG("ldo_reg_t_default[ldon-1]=0x%x,LDO_BUCKV1_TIME=0x%x\n",ldo_reg_t_default[ldon-1],LDO_BUCKV1_TIME);
- DBG("ldo_reg_t_default[ldon-1]<<LDO_BUCKV1_TIME=0x%x\n",ldo_reg_t_default[ldon-1]<<LDO_BUCKV1_TIME);
- DBG("ADDR=0x%x,reg_val=0x%x\n",LDO1_REG_ADDR+ldon-1,reg_val);
-
- if(lp8725_write_reg(lp8725_client,LDO1_REG_ADDR+ldon-1,reg_val)<0)
- {
- DBGERR("%s %d error\n",__FUNCTION__,__LINE__);
- return -1;
- }
-
- lp8725_regs.ldo_reg_val[ldon-1]=reg_val;
- return 0;
-}
-
-/* **********************************************************************
- * ÉèÖÃliloµÄÊä³öµçѹ
- *ldon:ldo±àºÅ Èçlilo1 lilon=1£¬vol µçѹµ¥Î»10mv Èç0.8v vol=80
- *µçѹ·¶Î§:µçѹÔÚ[0.8,1.4]ʱ²½½ø0.05v£¬µçѹÔÚ[1.4,3.3]ʱ²½½ø0.1v
- * return <0 failed
- * * ***********************************************************************/
-int lp8725_set_lilo_vol(uint8_t lilon,uint16_t vol)
-{
-
- uint8_t val=0;
- uint8_t reg_val=0;
- int i;
-
- if((vol>lilo_vol_range[LILO_RANG-1].vol_high)||(vol<lilo_vol_range[0].vol_low)||lilon>LP8725_LILO_NUM)
- return -1;
-
- for(i=0;i<LILO_RANG;i++)
- {
- if(vol<=lilo_vol_range[i].vol_high)
- {
- val+=(vol-lilo_vol_range[i].vol_low)/lilo_vol_range[i].rang;
- break;
- }
- else
- val+=(lilo_vol_range[i].vol_high-lilo_vol_range[i].vol_low)/lilo_vol_range[i].rang;
- }
-
- reg_val=(lilo_reg_t_default[lilon-1]<<LDO_BUCKV1_TIME)|val;
-
- if(lp8725_write_reg(lp8725_client,LILO1_REG_ADDR+lilon-1,reg_val)<0)
- {
- DBGERR("%s %d error\n",__FUNCTION__,__LINE__);
- return -1;
- }
-
- lp8725_regs.lilo_reg_val[lilon-1]=reg_val;
-
- return 0;
-}
-
-
-/* **********************************************************************
-* ÉèÖÃbuckµÄv1 v2 Êä³öµçѹ¿ØÖƼĴæÆ÷
-*ldon:ldo±àºÅ Èçbuck1 buckn=1£¬vol µçѹµ¥Î»10mv Èç0.8v vol=80 £¬v2=1 ½«µçѹֵдÈëv2 reg£¬·ñÔòдÈëv1 reg
-*µçѹ·¶Î§:µçѹÔÚ[0.8,1.4]ʱ²½½ø0.05v£¬µçѹÔÚ[1.4,1.7]ʱ²½½ø0.1v£¬
-*µçѹÔÚ[1.7,1.9]ʱ²½½ø0.05v£¬µçѹÔÚ[1.9,3.0]ʱ²½½ø0.1v
-* return <0 failed
-* * ***********************************************************************/
-static int lp8725_set_buck_vol_v1orv2(uint8_t buckn,uint16_t vol,uint8_t v2)
-{
-
- uint8_t val=0;
- uint8_t reg_val=0;
- uint8_t reg_addr=0;
- int i;
-
- if(vol>buck_vol_range[BULK_RANG-1].vol_high||vol<buck_vol_range[0].vol_low||buckn>LP8725_BUCK_NUM)
- return -1;
-
- for(i=0;i<BULK_RANG;i++)
- {
- if(vol<=buck_vol_range[i].vol_high)
- {
- val+=(vol-buck_vol_range[i].vol_low)/buck_vol_range[i].rang;
- break;
- }
- else
- val+=(buck_vol_range[i].vol_high-buck_vol_range[i].vol_low)/buck_vol_range[i].rang;
- }
-
- reg_addr=BUCK1_V1_REG_ADDR+(buckn-1)*2;
- reg_val=(buck_v1_reg_t_default[buckn-1]<<LDO_BUCKV1_TIME)|val;
-
- if(v2)
- reg_addr=BUCK1_V2_REG_ADDR+(buckn-1)*2;
-
-
- if(lp8725_write_reg(lp8725_client,reg_addr,reg_val)<0)
- {
- DBGERR("%s %d error\n",__FUNCTION__,__LINE__);
- return -1;
- }
-
- if(v2)
- lp8725_regs.buck_v2_reg_val[buckn-1]=reg_val;
- else
- lp8725_regs.buck_v1_reg_val[buckn-1]=reg_val;
-
- return 0;
-}
-/***************************************************************
-*
-*
-****************************************************************/
-int lp8725_set_buck_dvsn_v_bit(uint8_t buckn,uint8_t dvs)
-{
-
-
- uint8_t reg_val=0;
-
- if(dvs)
- reg_val=lp8725_regs.general_reg_val|(0x01<<(2+buckn-1));
- else
- reg_val=lp8725_regs.general_reg_val&(~0x01<<(12+buckn-1));
-
-
- if(lp8725_write_reg(lp8725_client,GENERAL_REG_ADDR,reg_val)<0)
- {
-
- DBGERR("%s %d error\n",__FUNCTION__,__LINE__);
- return -1;
- }
-
- lp8725_regs.general_reg_val=reg_val;
-
- return 0;
-}
-/* **********************************************************************
-* ÉèÖÃbuckµÄÊä³öµçѹ
-*ldon:ldo±àºÅ Èçbuck1 buckn=1£¬vol µçѹµ¥Î»10mv Èç0.8v vol=80
-*µçѹ·¶Î§:µçѹÔÚ[0.8,1.4]ʱ²½½ø0.05v£¬µçѹÔÚ[1.4,1.7]ʱ²½½ø0.1v£¬
-*µçѹÔÚ[1.7,1.9]ʱ²½½ø0.05v£¬µçѹÔÚ[1.9,3.0]ʱ²½½ø0.1v
-*ÿ¸öbuck ÓÐÁ½µçѹ¼Ä´æÆ÷v1¡¢v2£¬buck µÄÊä³öµçѹ¸ù¾ÝÒ»¶¨Ìõ¼þ£¬
-*Ñ¡Ôñ¸ù¾ÝÄǸö¼Ä´æÆ÷µÄÖµÊä³öµçѹ
-* buck1: dvs1_v=1 output vol depend on buck1_v1 reg,else depend on dvs pin. dvspin=1 output vol depend on buck1_v1,esle output vol depend on buck1_v2
-*buck2:dvs1_v=1 output vol depend on buck2_v1 reg,else depend on buck2_v2.
-* return <0 failed
-* * ***********************************************************************/
-
- int lp8725_set_buck_vol(uint8_t buckn,uint16_t vol)
- {
-
- if(lp8725_set_buck_vol_v1orv2(buckn,vol,0)<0)
- return -1;
-
- return lp8725_set_buck_vol_v1orv2(buckn,vol,1);
-
-}
-
-int get_dvs_pin_level(void)
-{
-
-// dvs pin is low return 0
-
-}
-int set_dvs_pin_level(uint8_t level)
-{
-
-
-
-}
-/*******************************************************************************
-*in sleep mode all pins val is low
-*reg SLEEP_MODE=0,and pin DVS=0£¬this ic enter into seelp mode
-********************************************************************************/
-int lp8725_setinto_sleep(uint8_t sleep)
-{
-
-
- uint8_t reg_val=0;
- set_dvs_pin_level(0);
-
- if(sleep)
- reg_val=lp8725_regs.general_reg_val|(0x01<<1);
- else
- reg_val=lp8725_regs.general_reg_val&(~0x01<<1);
- if(lp8725_write_reg(lp8725_client,GENERAL_REG_ADDR,reg_val)<0)
- {
-
- DBGERR("%s %d error\n",__FUNCTION__,__LINE__);
- return -1;
- }
- lp8725_regs.general_reg_val=reg_val;
- return 0;
-}
-/***************************************************************
-*
-*
-****************************************************************/
-int lp8725_buck_en(uint8_t buckn,uint8_t enble)
-{
-
-
- uint8_t reg_val=0;
-
- if(buckn==1)
- {
- if(enble)
- reg_val=lp8725_regs.general_reg_val|0x01;
- else
- reg_val=lp8725_regs.general_reg_val&(~0x01);
- }
-
- if(buckn==2)
- {
- if(enble)
- reg_val=lp8725_regs.general_reg_val|(0x01<<4);
- else
- reg_val=lp8725_regs.general_reg_val&(~0x01<<4);
- }
-
- if(lp8725_write_reg(lp8725_client,GENERAL_REG_ADDR,reg_val)<0)
- {
-
- DBGERR("%s %d error\n",__FUNCTION__,__LINE__);
- return -1;
- }
-
- lp8725_regs.general_reg_val=reg_val;
-
- return 0;
-}
-
-
-
-int lp8725_lilo_en(uint8_t lilon,uint8_t enble)
-{
- uint8_t reg_val=0;
-
- if(enble)
- reg_val=lp8725_regs.ldo_ctr_reg_val|(0x01<<(5+lilon-1));
- else
- reg_val=lp8725_regs.ldo_ctr_reg_val&(~(0x01<<(5+lilon-1)));
-
- if(lp8725_write_reg(lp8725_client,LDO_CTR_REG_ADDR,reg_val)<0)
- {
-
- DBGERR("%s %d error\n",__FUNCTION__,__LINE__);
- return -1;
- }
-
- lp8725_regs.ldo_ctr_reg_val=reg_val;
-
- return 0;
-}
-/***************************************************************
-*ldo3 is enbale if pin LdO3_EN=1 or LDO3 enable reg=1
-*
-****************************************************************/
-int lp8725_ldo_en(uint8_t ldo,uint8_t enble)
-{
-
-
- uint8_t reg_val=0;
-
- if(enble)
- reg_val=lp8725_regs.ldo_ctr_reg_val|(0x01<<(ldo-1));
- else
- reg_val=lp8725_regs.ldo_ctr_reg_val&(~(0x01<<(ldo-1)));
-
-
- if(lp8725_write_reg(lp8725_client,LDO_CTR_REG_ADDR,reg_val)<0)
- {
- DBGERR("%s %d error\n",__FUNCTION__,__LINE__);
- return -1;
- }
-
- lp8725_regs.ldo_ctr_reg_val=reg_val;
-
- return 0;
-}
-
-
-
-void lp8725_set_init(void)
-{
-
- uint8_t reg_val=0;
- uint8_t read_ret;
- lp8725_regs.general_reg_val=GENERAL_REG_DEFAULT;
- lp8725_regs.buck_ctr_reg_val=BUCK_CTR_REG_ADDR;
- lp8725_regs.pulldown_reg_val=PULLDOWN_REG_ADDR;
- lp8725_regs.status_reg_val=STATUS_REG_ADDR;
- /*
- ¿ª»úºóldo 1¡¢2¡¢5 lilo2ĬÈÏΪ¹Ø±Õ
- */
- DBG("**run in %s**\n",__FUNCTION__);
- //reg_val=LDO_CTR_REG_ADDR&&(~(1<<0))&&(~(1<<0))&&(~(1<<1))&&(~(1<<4))&&(~(1<<6));
- reg_val=0x7f;
- DBG("**lp8725_client=%s**LDO_CTR_REG_ADDR=%d**reg_val=%d\n",lp8725_client,LDO_CTR_REG_ADDR,reg_val);
- if(lp8725_write_reg(lp8725_client,LDO_CTR_REG_ADDR,reg_val)<0)
- {
- DBG("%s %d error\n",__FUNCTION__,__LINE__);
- return -1;
- }
-
- /*
- **set ldo4 VCCA 3.3V;ldo5 AVDD18 1.8v
- */
- lp8725_set_ldo_vol(4,330);
- lp8725_set_ldo_vol(5,180);
-
-
-
-
-
-
-#if 0
- DBG("**begin lp8725_read_reg %s %d \n",__FUNCTION__,__LINE__);
- if(lp8725_read_reg(lp8725_client,0x00,&read_ret)<0)
- {
- DBG("%s %d error\n",__FUNCTION__,__LINE__);
- return -1;
- }
- DBG("**lp8725_read_reg %s %d return read_ret = %d\n",__FUNCTION__,__LINE__,read_ret);
-#endif
-
- lp8725_regs.ldo_ctr_reg_val=reg_val;
-
- DBG("**run out %s**\n",__FUNCTION__);
-}
-
-#if 0
-static __init int seqgen1_init(void)
-{
- uint8_t *read_val;
- //uint8_t reg_val=0x98;
- DBG("**************run in %s\n",__FUNCTION__);
- //lp8725_set_ldo_vol(2,150);
- //lp8725_set_lilo_vol(2,150);
- //lp8725_set_buck_vol(2,170);
-
- while(1)
- {
- DBG("\n***lp8725_lilo_en(2,0)\n");
- lp8725_lilo_en(2,0);
- mdelay(6000);
- DBG("\n***lp8725_lilo_en(2,1)\n");
- lp8725_lilo_en(2,1);
- mdelay(6000);
- }
-
-#if 0
- while(1)
- {
- int i;
- for(i=180;i<=330;i=i-10)
- {
- DBG("\n\n**i=%d\n",i);
- DBG("**************run in %s\n",__FUNCTION__);
- lp8725_set_buck_vol(2,i);
- mdelay(3000);
- }
- }
- DBG("**************run out %s\n",__FUNCTION__);
-
-
- if(lp8725_write_reg(lp8725_client,LDO2_REG_ADDR,reg_val)<0)
- {
- DBG("%s %d error\n",__FUNCTION__,__LINE__);
- return -1;
- }
-
- while(1)
- {
- lp8725_read_reg(lp8725_client,LDO_CTR_REG_ADDR,read_val);
- DBG("\n*****read_val = %d\n",read_val);
- }
- DBG("**************run out %s\n",__FUNCTION__);
-#endif
- return 0;
-}
-late_initcall(seqgen1_init);
-#endif
-
-
-static int __devinit lp8725_probe(struct i2c_client *client,const struct i2c_device_id *id)
-{
- int ret;
-
- DBG("**%s in %d line,dev adr is %x**\n",__FUNCTION__,__LINE__,client->addr);
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
- return -EIO;
- lp8725_client=client;
- lp8725_set_init();
-
- DBG("**run out %s**\n",__FUNCTION__);
- return 0;
-}
-
-static int lp8725_remove(struct i2c_client *client)
-{
-
- return 0;
-}
-
-static struct i2c_driver lp8725_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "lp8725",
- },
- .probe = lp8725_probe,
- .remove = lp8725_remove,
- .id_table = lp8725_id,
-};
-
-static int __init lp8725_init(void)
-{
- int ret;
- ret = i2c_add_driver(&lp8725_driver);
- DBG("**lp8725_init return %d**\n",ret);
- return ret;
-}
-static void __exit lp8725_exit(void)
-{
- i2c_del_driver(&lp8725_driver);
-}
-
-module_init(lp8725_init);
-module_exit(lp8725_exit);
-MODULE_AUTHOR(" XXX XXX@rock-chips.com");
-MODULE_DESCRIPTION("Driver for rk2818 extend gpio device");
-MODULE_LICENSE("GPL");
-
-
three step-down converters and two general-purpose LDO voltage regulators.
It supports TI's software based Class-2 SmartReflex implementation.
+config RK2818_REGULATOR_LP8725
+ tristate "rk2818 pmic lp8725"
+ depends on I2C
+ help
+ Say Y to enable support for the voltage regulators pmic lp8725 on the RK2818.
endif
obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o
obj-$(CONFIG_REGULATOR_MC13783) += mc13783.o
obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o
+obj-$(CONFIG_RK2818_REGULATOR_LP8725) += rk2818_lp8725.o
obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o
obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o
--- /dev/null
+/* drivers/regulator/rk2818_lp8725.c
+ *
+ * Copyright (C) 2010 ROCKCHIP, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+/*******************************************************************/
+/* COPYRIGHT (C) ROCK-CHIPS FUZHOU . ALL RIGHTS RESERVED. */
+/*******************************************************************
+FILE : rk2818_lp8725.c
+DESC : LP8725 PMIC driver
+AUTHOR : cym
+DATE : 2010-08-06
+NOTES :
+$LOG: GPIO.C,V $
+REVISION 0.01
+********************************************************************/
+
+
+#include <linux/bug.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/regulator/driver.h>
+#include "rk2818_lp8725.h"
+
+
+#if 0
+#define DBG(x...) printk(KERN_INFO x)
+#else
+#define DBG(x...)
+#endif
+#if 1
+#define DBG_INFO(x...) printk(KERN_INFO x)
+#else
+#define DBG_INFO(x...)
+#endif
+
+
+
+
+struct lp8725 {
+ struct device *dev;
+ struct mutex io_lock;
+ struct i2c_client *i2c;
+ int num_regulators;
+ struct regulator_dev **rdev;
+};
+
+static u8 lp8725_reg_read(struct lp8725 *lp8725, u8 reg);
+static int lp8725_set_bits(struct lp8725 *lp8725, u8 reg, u16 mask, u16 val);
+
+
+
+#define LP8725_BUCK_VOL_ENABLE_REG 0x00
+#define LP8725_BUCK1_BASE 0x08
+#define LP8725_BUCK2_BASE 0x0A
+
+const static int buck_base_addr[] = {
+ LP8725_BUCK1_BASE,
+ LP8725_BUCK2_BASE,
+};
+
+
+
+#define LP8725_BUCK_TARGET_VOL1_REG(x) (buck_base_addr[x])
+#define LP8725_BUCK_TARGET_VOL2_REG(x) (buck_base_addr[x]+1)
+
+const static int buck_voltage_map[] = {
+ 800, 850, 900, 950, 1000, 1050, 1100, 1150,
+ 1200, 1250, 1300, 1350, 1400, 1500, 1600, 1700,
+ 1750, 1800, 1850, 1900, 2000, 2100, 2200, 2300,
+ 2400, 2500, 2600, 2700, 2800, 2850, 2900, 3000,
+};
+
+#define BUCK_TARGET_VOL_MASK 0x1f
+#define BUCK_TARGET_VOL_MIN_IDX 0x00
+#define BUCK_TARGET_VOL_MAX_IDX 0x1f
+
+
+
+#define LP8725_LDO_ENABLE_REG 0x0d
+#define LP8725_LDO_VOL_CONTR_BASE 0x01
+
+#define LP8725_LDO_VOL_CONTR_REG(x) (LP8725_LDO_VOL_CONTR_BASE + x)
+
+const static int ldo_voltage_map[] = {
+ 1200, 1250, 1300, 1350, 1400, 1450, 1500, 1550,
+ 1600, 1650, 1700, 1750, 1800, 1850, 1900, 2000,
+ 2100, 2200, 2300, 2400, 2500, 2600, 2650, 2700,
+ 2750, 2800, 2850, 2900, 2950, 3000, 3100, 3300,
+};
+
+#define LDO_VOL_CONTR_MASK 0x1f
+#define LDO_VOL_MIN_IDX 0x00
+#define LDO_VOL_MAX_IDX 0x1f
+
+#define LP8725_LILO_ENABLE_REG 0x0d
+#define LP8725_LILO_VOL_CONTR_BASE 0x06
+
+#define LP8725_LILO_VOL_CONTR_REG(x) (LP8725_LILO_VOL_CONTR_BASE + x)
+
+const static int lilo_voltage_map[] = {
+ 800, 850, 900, 950, 1000, 1050, 1100, 1150,
+ 1200, 1250, 1300, 1350, 1400, 1500, 1600, 1700,
+ 1800, 1900, 2000, 2100, 2200, 2300, 2400, 2500,
+ 2600, 2700, 2800, 2850, 2900, 3000, 3100, 3300,
+};
+
+#define LILO_VOL_CONTR_MASK 0x1f
+#define LILO_VOL_MIN_IDX 0x00
+#define LILO_VOL_MAX_IDX 0x1f
+
+
+static int lp8725_ldo_list_voltage(struct regulator_dev *dev, unsigned index)
+{
+ return 1000 * ldo_voltage_map[index];
+}
+
+static int lp8725_ldo_is_enabled(struct regulator_dev *dev)
+{
+ struct lp8725 *lp8725 = rdev_get_drvdata(dev);
+ int ldo = rdev_get_id(dev) - LP8725_LDO1;
+ u16 mask = 1 << (ldo);
+ u16 val;
+
+ val = lp8725_reg_read(lp8725, LP8725_LDO_ENABLE_REG);
+ return (val & mask) != 0;
+}
+
+static int lp8725_ldo_enable(struct regulator_dev *dev)
+{
+ struct lp8725 *lp8725 = rdev_get_drvdata(dev);
+ int ldo = rdev_get_id(dev) - LP8725_LDO1;
+ u16 mask = 1 << (ldo);
+ return lp8725_set_bits(lp8725, LP8725_LDO_ENABLE_REG, mask, mask);
+}
+
+static int lp8725_ldo_disable(struct regulator_dev *dev)
+{
+ struct lp8725 *lp8725 = rdev_get_drvdata(dev);
+ int ldo = rdev_get_id(dev) - LP8725_LDO1;
+ u16 mask = 1 << (ldo);
+ return lp8725_set_bits(lp8725, LP8725_LDO_ENABLE_REG, mask, 0);
+}
+
+static int lp8725_ldo_get_voltage(struct regulator_dev *dev)
+{
+ struct lp8725 *lp8725 = rdev_get_drvdata(dev);
+ int ldo = rdev_get_id(dev) - LP8725_LDO1;
+ u16 reg;
+ u32 val;
+
+ reg = lp8725_reg_read(lp8725, LP8725_LDO_VOL_CONTR_REG(ldo));
+ reg &= BUCK_TARGET_VOL_MASK;
+
+ val = 1000 * ldo_voltage_map[reg];
+ return val;
+}
+
+static int lp8725_ldo_set_voltage(struct regulator_dev *dev,
+ int min_uV, int max_uV)
+{
+ struct lp8725 *lp8725 = rdev_get_drvdata(dev);
+ int ldo = rdev_get_id(dev) - LP8725_LDO1;
+ int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
+ const int *vol_map = ldo_voltage_map;
+ u16 val;
+
+ if (min_vol < vol_map[LDO_VOL_MIN_IDX] ||
+ min_vol > vol_map[LDO_VOL_MAX_IDX])
+ return -EINVAL;
+
+ for (val = LDO_VOL_MIN_IDX; val <= LDO_VOL_MAX_IDX; val++)
+ if (vol_map[val] >= min_vol)
+ break;
+
+ if (vol_map[val] > max_vol)
+ return -EINVAL;
+
+ DBG("***run in %s %d reg=0x%x val=0x%x",__FUNCTION__,__LINE__,LP8725_LDO_VOL_CONTR_REG(ldo),val);
+
+ return lp8725_set_bits(lp8725, LP8725_LDO_VOL_CONTR_REG(ldo),
+ LDO_VOL_CONTR_MASK, val);
+}
+
+static struct regulator_ops lp8725_ldo_ops = {
+ .list_voltage = lp8725_ldo_list_voltage,
+ .is_enabled = lp8725_ldo_is_enabled,
+ .enable = lp8725_ldo_enable,
+ .disable = lp8725_ldo_disable,
+ .get_voltage = lp8725_ldo_get_voltage,
+ .set_voltage = lp8725_ldo_set_voltage,
+};
+
+static int lp8725_lilo_list_voltage(struct regulator_dev *dev, unsigned index)
+{
+ return 1000 * lilo_voltage_map[index];
+}
+
+static int lp8725_lilo_is_enabled(struct regulator_dev *dev)
+{
+ struct lp8725 *lp8725 = rdev_get_drvdata(dev);
+ int lilo = rdev_get_id(dev) - LP8725_LILO1;
+ u16 mask = 1 << (lilo+4);
+ u16 val;
+
+ val = lp8725_reg_read(lp8725, LP8725_LILO_ENABLE_REG);
+ return (val & mask) != 0;
+}
+
+static int lp8725_lilo_enable(struct regulator_dev *dev)
+{
+ struct lp8725 *lp8725 = rdev_get_drvdata(dev);
+ int lilo = rdev_get_id(dev) - LP8725_LILO1;
+ u16 mask = 1 << (lilo+4);
+
+ return lp8725_set_bits(lp8725, LP8725_LILO_ENABLE_REG, mask, mask);
+}
+
+static int lp8725_lilo_disable(struct regulator_dev *dev)
+{
+ struct lp8725 *lp8725 = rdev_get_drvdata(dev);
+ int lilo = rdev_get_id(dev) - LP8725_LILO1;
+ u16 mask = 1 << (lilo+4);
+
+ return lp8725_set_bits(lp8725, LP8725_LILO_ENABLE_REG, mask, 0);
+}
+
+static int lp8725_lilo_get_voltage(struct regulator_dev *dev)
+{
+ struct lp8725 *lp8725 = rdev_get_drvdata(dev);
+ int lilo = rdev_get_id(dev) - LP8725_LILO1;
+ u16 reg;
+ u32 val;
+
+ reg = lp8725_reg_read(lp8725, LP8725_LILO_VOL_CONTR_REG(lilo));
+ reg &= BUCK_TARGET_VOL_MASK;
+
+ val = 1000 * lilo_voltage_map[reg];
+ return val;
+}
+
+static int lp8725_lilo_set_voltage(struct regulator_dev *dev,
+ int min_uV, int max_uV)
+{
+ struct lp8725 *lp8725 = rdev_get_drvdata(dev);
+ int lilo = rdev_get_id(dev) - LP8725_LILO1;
+ int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
+ const int *vol_map = lilo_voltage_map;
+ u16 val;
+
+ if (min_vol < vol_map[LILO_VOL_MIN_IDX] ||
+ min_vol > vol_map[LILO_VOL_MAX_IDX])
+ return -EINVAL;
+
+ for (val = LILO_VOL_MIN_IDX; val <= LILO_VOL_MAX_IDX; val++)
+ if (vol_map[val] >= min_vol)
+ break;
+
+ if (vol_map[val] > max_vol)
+ return -EINVAL;
+
+ return lp8725_set_bits(lp8725, LP8725_LILO_VOL_CONTR_REG(lilo),
+ LILO_VOL_CONTR_MASK, val);
+}
+
+static struct regulator_ops lp8725_lilo_ops = {
+ .list_voltage = lp8725_lilo_list_voltage,
+ .is_enabled = lp8725_lilo_is_enabled,
+ .enable = lp8725_lilo_enable,
+ .disable = lp8725_lilo_disable,
+ .get_voltage = lp8725_lilo_get_voltage,
+ .set_voltage = lp8725_lilo_set_voltage,
+};
+
+static int lp8725_dcdc_list_voltage(struct regulator_dev *dev, unsigned index)
+{
+ return 1000 * buck_voltage_map[index];
+}
+
+static int lp8725_dcdc_is_enabled(struct regulator_dev *dev)
+{
+ struct lp8725 *lp8725 = rdev_get_drvdata(dev);
+ int buck = rdev_get_id(dev) - LP8725_DCDC1;
+ u16 mask = 1 << (buck * 2);
+ u16 val;
+
+ val = lp8725_reg_read(lp8725, LP8725_BUCK_VOL_ENABLE_REG);
+ return (val & mask) != 0;
+}
+
+static int lp8725_dcdc_enable(struct regulator_dev *dev)
+{
+ struct lp8725 *lp8725 = rdev_get_drvdata(dev);
+ int buck = rdev_get_id(dev) - LP8725_DCDC1;
+ u16 mask = 1 << (buck * 2);
+
+ return lp8725_set_bits(lp8725, LP8725_BUCK_VOL_ENABLE_REG, mask, mask);
+}
+
+static int lp8725_dcdc_disable(struct regulator_dev *dev)
+{
+ struct lp8725 *lp8725 = rdev_get_drvdata(dev);
+ int buck = rdev_get_id(dev) - LP8725_DCDC1;
+ u16 mask = 1 << (buck * 2);
+
+ return lp8725_set_bits(lp8725, LP8725_BUCK_VOL_ENABLE_REG, mask, 0);
+}
+
+static int lp8725_dcdc_get_voltage(struct regulator_dev *dev)
+{
+ struct lp8725 *lp8725 = rdev_get_drvdata(dev);
+ int buck = rdev_get_id(dev) - LP8725_DCDC1;
+ u16 reg;
+ int val;
+
+ reg = lp8725_reg_read(lp8725, LP8725_BUCK_TARGET_VOL1_REG(buck));
+ reg &= BUCK_TARGET_VOL_MASK;
+
+ val = 1000 * buck_voltage_map[reg];
+
+ return val;
+}
+
+static int lp8725_dcdc_set_voltage(struct regulator_dev *dev,
+ int min_uV, int max_uV)
+{
+ struct lp8725 *lp8725 = rdev_get_drvdata(dev);
+ int buck = rdev_get_id(dev) - LP8725_DCDC1;
+ int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
+ const int *vol_map = buck_voltage_map;
+ u16 val;
+ int ret;
+
+ if (min_vol < vol_map[BUCK_TARGET_VOL_MIN_IDX] ||
+ min_vol > vol_map[BUCK_TARGET_VOL_MAX_IDX])
+ return -EINVAL;
+
+ for (val = BUCK_TARGET_VOL_MIN_IDX; val <= BUCK_TARGET_VOL_MAX_IDX;
+ val++)
+ if (vol_map[val] >= min_vol)
+ break;
+
+ if (vol_map[val] > max_vol)
+ return -EINVAL;
+
+ ret = lp8725_set_bits(lp8725, LP8725_BUCK_TARGET_VOL1_REG(buck),
+ BUCK_TARGET_VOL_MASK, val);
+ if (ret)
+ return ret;
+
+ ret = lp8725_set_bits(lp8725, LP8725_BUCK_TARGET_VOL2_REG(buck),
+ BUCK_TARGET_VOL_MASK, val);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+static struct regulator_ops lp8725_dcdc_ops = {
+ .list_voltage = lp8725_dcdc_list_voltage,
+ .is_enabled = lp8725_dcdc_is_enabled,
+ .enable = lp8725_dcdc_enable,
+ .disable = lp8725_dcdc_disable,
+ .get_voltage = lp8725_dcdc_get_voltage,
+ .set_voltage = lp8725_dcdc_set_voltage,
+};
+
+static struct regulator_desc regulators[] = {
+ {
+ .name = "LDO1",
+ .id = LP8725_LDO1,
+ .ops = &lp8725_ldo_ops,
+ .n_voltages = ARRAY_SIZE(ldo_voltage_map),
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+ },
+ {
+ .name = "LDO2",
+ .id = LP8725_LDO2,
+ .ops = &lp8725_ldo_ops,
+ .n_voltages = ARRAY_SIZE(ldo_voltage_map),
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+ },
+ {
+ .name = "LDO3",
+ .id = LP8725_LDO3,
+ .ops = &lp8725_ldo_ops,
+ .n_voltages = ARRAY_SIZE(ldo_voltage_map),
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+ },
+ {
+ .name = "LDO4",
+ .id = LP8725_LDO4,
+ .ops = &lp8725_ldo_ops,
+ .n_voltages = ARRAY_SIZE(ldo_voltage_map),
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+ },
+ {
+ .name = "LDO5",
+ .id = LP8725_LDO5,
+ .ops = &lp8725_ldo_ops,
+ .n_voltages = ARRAY_SIZE(ldo_voltage_map),
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+ },
+ {
+ .name = "LILO1",
+ .id = LP8725_LILO1,
+ .ops = &lp8725_lilo_ops,
+ .n_voltages = ARRAY_SIZE(lilo_voltage_map),
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+ },
+ {
+ .name = "LILO2",
+ .id = LP8725_LILO2,
+ .ops = &lp8725_lilo_ops,
+ .n_voltages = ARRAY_SIZE(lilo_voltage_map),
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+ },
+ {
+ .name = "DCDC1",
+ .id = LP8725_DCDC1,
+ .ops = &lp8725_dcdc_ops,
+ .n_voltages = ARRAY_SIZE(buck_voltage_map),
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+ },
+ {
+ .name = "DCDC2",
+ .id = LP8725_DCDC2,
+ .ops = &lp8725_dcdc_ops,
+ .n_voltages = ARRAY_SIZE(buck_voltage_map),
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int lp8725_i2c_read(struct i2c_client *i2c, char reg, int count, u16 *dest)
+{
+ int ret;
+ struct i2c_adapter *adap;
+ struct i2c_msg msgs[2];
+
+ if(!i2c)
+ return ret;
+
+ if (count != 1)
+ return -EIO;
+
+ adap = i2c->adapter;
+
+ msgs[0].addr = i2c->addr;
+ msgs[0].buf = ®
+ msgs[0].flags = i2c->flags;
+ msgs[0].len = 1;
+ msgs[0].scl_rate = 200*1000;
+
+ msgs[1].buf = dest;
+ msgs[1].addr = i2c->addr;
+ msgs[1].flags = i2c->flags | I2C_M_RD;
+ msgs[1].len = 1;
+ msgs[1].scl_rate = 200*1000;
+ ret = i2c_transfer(adap, msgs, 2);
+
+ DBG("***run in %s %d msgs[1].buf = %d\n",__FUNCTION__,__LINE__,*(msgs[1].buf));
+
+ return 0;
+}
+
+static int lp8725_i2c_write(struct i2c_client *i2c, char reg, int count, const u16 src)
+{
+ int ret=-1;
+
+ struct i2c_adapter *adap;
+ struct i2c_msg msg;
+ char tx_buf[2];
+
+ if(!i2c)
+ return ret;
+ if (count != 1)
+ return -EIO;
+
+ adap = i2c->adapter;
+ tx_buf[0] = reg;
+ tx_buf[1] = src;
+
+ msg.addr = i2c->addr;
+ msg.buf = &tx_buf[0];
+ msg.len = 1 +1;
+ msg.flags = i2c->flags;
+ msg.scl_rate = 200*1000;
+
+ ret = i2c_transfer(adap, &msg, 1);
+ return ret;
+}
+
+static u8 lp8725_reg_read(struct lp8725 *lp8725, u8 reg)
+{
+ u16 val = 0;
+
+ mutex_lock(&lp8725->io_lock);
+
+ lp8725_i2c_read(lp8725->i2c, reg, 1, &val);
+
+ DBG("reg read 0x%02x -> 0x%02x\n", (int)reg, (unsigned)val&0xff);
+
+ mutex_unlock(&lp8725->io_lock);
+
+ return val & 0xff;
+}
+
+static int lp8725_set_bits(struct lp8725 *lp8725, u8 reg, u16 mask, u16 val)
+{
+ u16 tmp;
+ int ret;
+
+ mutex_lock(&lp8725->io_lock);
+
+ ret = lp8725_i2c_read(lp8725->i2c, reg, 1, &tmp);
+ tmp = (tmp & ~mask) | val;
+ if (ret == 0) {
+ ret = lp8725_i2c_write(lp8725->i2c, reg, 1, tmp);
+ DBG("reg write 0x%02x -> 0x%02x\n", (int)reg, (unsigned)val&0xff);
+ }
+ mutex_unlock(&lp8725->io_lock);
+
+ return ret;
+}
+
+
+static int lp8725_set_init(void)
+{
+ int ret;
+ int tmp = 0;
+ struct regulator *ldo1,*ldo2,*ldo3,*ldo4,*ldo5;
+ struct regulator *lilo1,*lilo2;
+ struct regulator *buck1,*buck2;
+
+ DBG_INFO("***run in %s %d ",__FUNCTION__,__LINE__);
+
+ /*init ldo1*/
+ DBG_INFO("***ldo1 vcc init\n");
+ ldo1 = regulator_get(NULL, "ldo1");
+ regulator_enable(ldo1);
+// regulator_set_voltage(ldo1,2500000,2500000);
+ tmp = regulator_get_voltage(ldo1);
+ DBG_INFO("***regulator_set_init: ldo1 vcc =%d\n",tmp);
+
+ /*init ldo2*/
+ DBG_INFO("***ldo2 vcc init\n");
+ ldo2 = regulator_get(NULL, "ldo2");
+ regulator_enable(ldo2);
+// regulator_set_voltage(ldo2,3000000,3000000);
+ tmp = regulator_get_voltage(ldo2);
+ DBG_INFO("***regulator_set_init: ldo2 vcc =%d\n",tmp);
+
+ /*init ldo3*/
+ DBG_INFO("***ldo3 vcc init\n");
+ ldo3 = regulator_get(NULL, "ldo3");
+ regulator_enable(ldo3);
+// regulator_set_voltage(ldo3,3000000,3000000);
+ tmp = regulator_get_voltage(ldo3);
+ DBG_INFO("***regulator_set_init: ldo3 vcc =%d\n",tmp);
+
+ /*init ldo4*/
+ DBG_INFO("***ldo4 vcc init\n");
+ ldo4 = regulator_get(NULL, "ldo4");
+ regulator_enable(ldo4);
+// regulator_set_voltage(ldo4,1900000,1900000);
+ tmp = regulator_get_voltage(ldo4);
+ DBG_INFO("***regulator_set_init: ldo4 vcc =%d\n",tmp);
+
+ /*init ldo5*/
+ DBG_INFO("***ldo5 vcc init\n");
+ ldo5 = regulator_get(NULL, "ldo5");
+ regulator_enable(ldo5);
+// regulator_set_voltage(ldo5,1900000,1900000);
+ tmp = regulator_get_voltage(ldo5);
+ DBG_INFO("***regulator_set_init: ldo5 vcc =%d\n",tmp);
+
+ /*init lilo1*/
+ DBG_INFO("***lilo1 vcc init\n");
+ lilo1 = regulator_get(NULL, "lilo1");
+ regulator_enable(lilo1);
+// regulator_set_voltage(lilo1,3300000,3300000);
+ tmp = regulator_get_voltage(lilo1);
+ DBG_INFO("***regulator_set_init: lilo1 vcc =%d\n",tmp);
+
+ /*init lilo2*/
+ DBG_INFO("***lilo2 vcc init\n");
+ lilo2 = regulator_get(NULL, "lilo2");
+ regulator_enable(lilo2);
+// regulator_set_voltage(lilo2,3300000,3300000);
+ tmp = regulator_get_voltage(lilo2);
+ DBG_INFO("***regulator_set_init: lilo2 vcc =%d\n",tmp);
+
+ /*init buck1*/
+ DBG_INFO("***buck1 vcc init\n");
+ buck1 = regulator_get(NULL, "vdd12");
+ regulator_set_voltage(buck1,1200000,1200000);
+ tmp = regulator_get_voltage(buck1);
+ DBG_INFO("***regulator_set_init: buck1 vcc =%d\n",tmp);
+
+ /*init buck2*/
+ DBG_INFO("***buck2 vcc init\n");
+ buck2 = regulator_get(NULL, "vccdr");
+// regulator_set_voltage(buck1,1800000,1800000);
+ tmp = regulator_get_voltage(buck2);
+ DBG_INFO("***regulator_set_init: buck2 vcc =%d\n",tmp);
+
+ return(0);
+}
+
+
+static int setup_regulators(struct lp8725 *lp8725, struct lp8725_platform_data *pdata)
+{
+ int i, err;
+ int num_regulators = pdata->num_regulators;
+ lp8725->num_regulators = num_regulators;
+ lp8725->rdev = kzalloc(sizeof(struct regulator_dev *) * num_regulators,
+ GFP_KERNEL);
+
+ /* Instantiate the regulators */
+ for (i = 0; i < num_regulators; i++) {
+ int id = pdata->regulators[i].id;
+ lp8725->rdev[i] = regulator_register(®ulators[id],
+ lp8725->dev, pdata->regulators[i].initdata, lp8725);
+
+ err = IS_ERR(lp8725->rdev[i]);
+ if (err) {
+ dev_err(lp8725->dev, "regulator init failed: %d\n",
+ err);
+ goto error;
+ }
+ }
+
+ return 0;
+error:
+ for (i = 0; i < num_regulators; i++)
+ if (lp8725->rdev[i])
+ regulator_unregister(lp8725->rdev[i]);
+ kfree(lp8725->rdev);
+ lp8725->rdev = NULL;
+ return err;
+}
+
+static int __devinit lp8725_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
+{
+ struct lp8725 *lp8725;
+ struct lp8725_platform_data *pdata = i2c->dev.platform_data;
+ int ret;
+
+ lp8725 = kzalloc(sizeof(struct lp8725), GFP_KERNEL);
+ if (lp8725 == NULL) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ lp8725->i2c = i2c;
+ lp8725->dev = &i2c->dev;
+ i2c_set_clientdata(i2c, lp8725);
+
+ mutex_init(&lp8725->io_lock);
+
+ if (pdata) {
+ ret = setup_regulators(lp8725, pdata);
+ if (ret < 0)
+ goto err;
+ } else
+ dev_warn(lp8725->dev, "No platform init data supplied\n");
+
+ lp8725_set_init();
+
+ return 0;
+
+err:
+ return ret;
+}
+
+static int __devexit lp8725_i2c_remove(struct i2c_client *i2c)
+{
+ struct lp8725 *lp8725 = i2c_get_clientdata(i2c);
+ int i;
+ for (i = 0; i < lp8725->num_regulators; i++)
+ if (lp8725->rdev[i])
+ regulator_unregister(lp8725->rdev[i]);
+ kfree(lp8725->rdev);
+ i2c_set_clientdata(i2c, NULL);
+ kfree(lp8725);
+
+ return 0;
+}
+
+static const struct i2c_device_id lp8725_i2c_id[] = {
+ { "lp8725", 0 },
+ { }
+};
+
+MODULE_DEVICE_TABLE(i2c, lp8725_i2c_id);
+
+static struct i2c_driver lp8725_i2c_driver = {
+ .driver = {
+ .name = "lp8725",
+ .owner = THIS_MODULE,
+ },
+ .probe = lp8725_i2c_probe,
+ .remove = __devexit_p(lp8725_i2c_remove),
+ .id_table = lp8725_i2c_id,
+};
+
+static int __init lp8725_module_init(void)
+{
+ int ret;
+
+ ret = i2c_add_driver(&lp8725_i2c_driver);
+ if (ret != 0)
+ pr_err("Failed to register I2C driver: %d\n", ret);
+
+ return ret;
+}
+module_init(lp8725_module_init);
+
+static void __exit lp8725_module_exit(void)
+{
+ i2c_del_driver(&lp8725_i2c_driver);
+}
+module_exit(lp8725_module_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("cym <cym@rock-chips.com>");
+MODULE_DESCRIPTION("LP8725 PMIC driver");
--- /dev/null
+/* include/linux/regulator/rk2818_lp8725.h
+ *
+ * Copyright (C) 2010 ROCKCHIP, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef __LINUX_REGULATOR_LP8725_H
+#define __LINUX_REGULATOR_LP8725_H
+
+#include <linux/regulator/machine.h>
+
+#define LP8725_LDO1 0
+#define LP8725_LDO2 1
+#define LP8725_LDO3 2
+#define LP8725_LDO4 3
+#define LP8725_LDO5 4
+
+#define LP8725_LILO1 5
+#define LP8725_LILO2 6
+
+#define LP8725_DCDC1 7
+#define LP8725_DCDC2 8
+
+#define LP8725_NUM_REGULATORS 9
+
+struct lp8725_regulator_subdev {
+ int id;
+ struct regulator_init_data *initdata;
+};
+
+struct lp8725_platform_data {
+ int num_regulators;
+ struct lp8725_regulator_subdev *regulators;
+};
+
+#endif