From: cym <709866821@qq.com> Date: Wed, 11 Aug 2010 02:26:40 +0000 (+0800) Subject: modified pmu_lp8725 and real kernel regulator interface function X-Git-Tag: firefly_0821_release~11282 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=882ddc0c29d20ed5dff80daae88dc93142ad7fe2;p=firefly-linux-kernel-4.4.55.git modified pmu_lp8725 and real kernel regulator interface function --- diff --git a/arch/arm/mach-rk2818/board-raho.c b/arch/arm/mach-rk2818/board-raho.c index 691359beba2d..460cabd2dc6b 100755 --- a/arch/arm/mach-rk2818/board-raho.c +++ b/arch/arm/mach-rk2818/board-raho.c @@ -49,7 +49,7 @@ #include "devices.h" #include "../../../drivers/spi/rk2818_spim.h" - +#include "../../../drivers/regulator/rk2818_lp8725.h" /* -------------------------------------------------------------------- * ÉùÃ÷ÁËrk2818_gpioBankÊý×飬²¢¶¨ÒåÁËGPIO¼Ä´æÆ÷×éIDºÍ¼Ä´æÆ÷»ùµØÖ·¡£ * -------------------------------------------------------------------- */ @@ -264,6 +264,241 @@ struct pca9554_platform_data rk2818_pca9554_data={ }; #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 @@ -365,11 +600,12 @@ static struct i2c_board_info __initdata board_i2c1_devices[] = { .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) diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index b5d5f6274030..f909f2f8f9fc 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -115,10 +115,4 @@ config BATTERY_RK2818 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 diff --git a/drivers/power/Makefile b/drivers/power/Makefile index 3be2b815dfb7..10caf2200b85 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -30,4 +30,3 @@ obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o 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 diff --git a/drivers/power/pmic_lp8725.c b/drivers/power/pmic_lp8725.c deleted file mode 100644 index 8ca1dbc7e586..000000000000 --- a/drivers/power/pmic_lp8725.c +++ /dev/null @@ -1,780 +0,0 @@ -/* 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#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)||(volLP8725_LDO_NUM) - return -1; - - for(i=0;ililo_vol_range[LILO_RANG-1].vol_high)||(volLP8725_LILO_NUM) - return -1; - - for(i=0;ibuck_vol_range[BULK_RANG-1].vol_high||volLP8725_BUCK_NUM) - return -1; - - for(i=0;iaddr); - 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"); - - diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index bcbb161bde0b..8d02f0fccfcd 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -157,5 +157,10 @@ config REGULATOR_TPS6507X 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 diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 4257a8683778..508b3560fd38 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o 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 diff --git a/drivers/regulator/rk2818_lp8725.c b/drivers/regulator/rk2818_lp8725.c new file mode 100644 index 000000000000..a4c59502cc4f --- /dev/null +++ b/drivers/regulator/rk2818_lp8725.c @@ -0,0 +1,746 @@ +/* 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 +#include +#include +#include +#include +#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 "); +MODULE_DESCRIPTION("LP8725 PMIC driver"); diff --git a/drivers/regulator/rk2818_lp8725.h b/drivers/regulator/rk2818_lp8725.h new file mode 100644 index 000000000000..74caf43d8fd9 --- /dev/null +++ b/drivers/regulator/rk2818_lp8725.h @@ -0,0 +1,44 @@ +/* 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 + +#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