change charge current
authorhxy <hxy@rock-chips.com>
Sat, 4 Sep 2010 12:35:24 +0000 (20:35 +0800)
committerhxy <hxy@rock-chips.com>
Sat, 4 Sep 2010 12:35:24 +0000 (20:35 +0800)
arch/arm/mach-rk2818/board-raho.c
drivers/power/rk2818_battery.c [changed mode: 0755->0644]
drivers/regulator/Kconfig
drivers/regulator/Makefile
drivers/regulator/charge-regulator.c [new file with mode: 0644]
include/linux/regulator/charge-regulator.h [new file with mode: 0644]

index 197e5c84b6e2ecd3977437f70e0c3631884a16c9..b03a9a82a05244b377c8f85d2e4d92ec9b461f7a 100644 (file)
 #include <mach/gpio.h>
 #include <mach/spi_fpga.h>
 #include <mach/rk2818_camera.h>                          /* ddl@rock-chips.com : camera support */
+#include <linux/pda_power.h>
+#include <linux/regulator/charge-regulator.h>
+#include <linux/regulator/machine.h>
+#include <linux/usb/gpio_vbus.h>
 #include <mach/rk2818_nand.h>
 
 #include <linux/mtd/nand.h>
@@ -821,6 +825,125 @@ static struct i2c_board_info __initdata board_i2c3_devices[] = {
 #endif
 };     
 
+/*
+ * External power
+ */
+
+static int power_supply_init(struct device *dev)
+{
+       return gpio_request(FPGA_PIO2_08, "AC charger detect");
+}
+
+static int rk2818_is_ac_online(void)
+{
+       return !gpio_get_value(FPGA_PIO2_08);
+}
+
+static void power_supply_exit(struct device *dev)
+{
+       gpio_free(FPGA_PIO2_08);
+}
+
+static char *rk2818_supplicant[] = {
+       "rk2818-battery"
+};
+
+static struct pda_power_pdata power_supply_info = {
+       .init            = power_supply_init,
+       .is_ac_online    = rk2818_is_ac_online,
+       .exit            = power_supply_exit,
+       .supplied_to     = rk2818_supplicant,
+       .num_supplicants = ARRAY_SIZE(rk2818_supplicant),
+};
+
+static struct resource power_supply_resources[] = {
+       [0] = {
+               .name  = "ac",
+               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
+                        IORESOURCE_IRQ_LOWEDGE,
+       },
+       [1] = {
+               .name  = "usb",
+               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
+                        IORESOURCE_IRQ_LOWEDGE,
+       },
+};
+
+static struct platform_device power_supply = {
+       .name = "pda-power",
+       .id   = -1,
+       .dev  = {
+               .platform_data = &power_supply_info,
+       },
+       .resource      = power_supply_resources,
+       .num_resources = ARRAY_SIZE(power_supply_resources),
+};
+
+/*
+ * USB "Transceiver"
+ */
+
+static struct resource gpio_vbus_resource = {
+       .flags = IORESOURCE_IRQ,
+       .start =  IRQ_NR_OTG,
+       .end   = IRQ_NR_OTG,
+};
+
+static struct gpio_vbus_mach_info gpio_vbus_info = {
+       .gpio_vbus   = FPGA_PIO4_06,
+};
+
+static struct platform_device gpio_vbus = {
+       .name          = "gpio-vbus",
+       .id            = -1,
+       .num_resources = 1,
+       .resource      = &gpio_vbus_resource,
+       .dev = {
+               .platform_data = &gpio_vbus_info,
+       },
+};
+
+/*
+ * Battery charger
+ */
+
+static struct regulator_consumer_supply rk2818_consumers[] = {
+       {
+               .dev=&rk2818_device_battery.dev,
+               .supply = "battery",
+       },
+       {
+               .dev = &gpio_vbus.dev,
+               .supply = "vbus_draw",
+       },
+       {
+               .dev = &power_supply.dev,
+               .supply = "ac_draw",
+       },
+};
+
+static struct regulator_init_data charge_init_data = {
+       .constraints = {
+               .max_uA         = 1200000,
+               .valid_ops_mask = REGULATOR_CHANGE_CURRENT,
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(rk2818_consumers),
+       .consumer_supplies      = rk2818_consumers,
+};
+
+static struct charge_platform_data charge_current_info = {
+       .gpio_charge = FPGA_PIO2_08,
+       .init_data  = &charge_init_data,
+};
+
+static struct platform_device charge_current = {
+       .name = "charge-regulator",
+       .id   = -1,
+       .dev  = {
+               .platform_data = &charge_current_info,
+       },
+};
+
 /*****************************************************************************************
  * camera  devices
  * author: ddl@rock-chips.com
@@ -1708,6 +1831,10 @@ static struct platform_device *devices[] __initdata = {
 #endif
        &rk2818_device_adc,
        &rk2818_device_adckey,
+#if defined(CONFIG_RK2818_REGULATOR_CHARGE)
+       &power_supply,
+       &charge_current,
+#endif
        &rk2818_device_battery,
     &rk2818_device_fb,    
     &rk2818_device_backlight,
old mode 100755 (executable)
new mode 100644 (file)
index ebed723..8f01bee
@@ -17,6 +17,7 @@
 #include <linux/err.h>
 #include <linux/platform_device.h>
 #include <linux/power_supply.h>
+#include <linux/regulator/consumer.h>
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
@@ -98,7 +99,7 @@ int gBatSlopeLevel = SLOPE_LOW_LEVEL;
 int gBatVoltageLevel = VOLTAGE_MID_LEVEL;
 int gBatUseStatus = BAT_LOADER_STATUS; 
 
-
+static struct regulator *pChargeregulator;
 
 extern int dwc_vbus_status(void);
 extern int get_msc_connect_flag(void);
@@ -146,11 +147,19 @@ static int rk2818_get_charge_status(void)
 {
        //DBG("gAdcValue[CHN_USB_ADC]=%d\n",gAdcValue[CHN_USB_ADC]);
        if(gAdcValue[CHN_USB_ADC] > 250)        //about 0.5V
-       return 1;               
+               {
+               return 1;
+               }
        else if((1 == dwc_vbus_status())&& (0 == get_msc_connect_flag()))
-       return 1;
+               {
+                 regulator_set_current_limit(pChargeregulator,0,1200000);
+               return 1;
+               }
        else
-       return 0;
+               {
+               regulator_set_current_limit(pChargeregulator,0,475000);
+               return 0;
+               }
 }
 
 static void rk2818_get_bat_status(struct rk2818_battery_data *bat)
@@ -612,6 +621,13 @@ static int rk2818_battery_probe(struct platform_device *pdev)
                goto err_battery_failed;
        }
        platform_set_drvdata(pdev, data);
+       
+
+       pChargeregulator = regulator_get(&pdev->dev, "battery");
+       if(IS_ERR(pChargeregulator))
+               printk(KERN_ERR"fail to get regulator battery\n");
+       else
+               regulator_set_current_limit(pChargeregulator,0,475000);
 
        INIT_WORK(&data->timer_work, rk2818_battery_timer_work);
        gBatteryData = data;
index 8d02f0fccfcdce9fc63a3f14ee5aef1e2e87d59a..b833192d75c26be890801b5b2a0e8d04d4b50c47 100644 (file)
@@ -156,6 +156,10 @@ config REGULATOR_TPS6507X
          This driver supports TPS6507X voltage regulator chips. TPS6507X provides
          three step-down converters and two general-purpose LDO voltage regulators.
          It supports TI's software based Class-2 SmartReflex implementation.
+config RK2818_REGULATOR_CHARGE
+       tristate "rk2818 Charger IC"
+       help
+         Say Y to enable support for the current regulators charge on the RK2818.
 
 config RK2818_REGULATOR_LP8725
        tristate "rk2818 pmic lp8725"
index 508b3560fd384d62af7cf5ce9fbed380730cdb23..c19b61747f0bf595687a2c0fcc52a929df81f35e 100644 (file)
@@ -23,6 +23,7 @@ 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_RK2818_REGULATOR_CHARGE) += charge-regulator.o
 
 obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o
 obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o
diff --git a/drivers/regulator/charge-regulator.c b/drivers/regulator/charge-regulator.c
new file mode 100644 (file)
index 0000000..e544862
--- /dev/null
@@ -0,0 +1,180 @@
+/* drivers/regulator/charge-regulator.c\r
+ *
+ * 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           :               charge-regulator.c\r
+DESC           :       charge current change driver\r
+AUTHOR         :       hxy\r
+DATE           :       2010-09-02\r
+NOTES          :
+$LOG: GPIO.C,V $
+REVISION 0.01
+********************************************************************/
+
+
+#include <linux/bug.h>
+#include <linux/err.h>\r
+#include <linux/platform_device.h>\r
+#include <linux/kernel.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/charge-regulator.h>\r
+#include <linux/gpio.h>\r
+
+
+#if 0
+#define DBG(x...)      printk(KERN_INFO x)
+#else
+#define DBG(x...)
+#endif
+\r
+\r
+const static int charge_current_map[] = {\r
+       475, 1200,\r
+};\r
+
+static int charge_current_is_enabled(struct regulator_dev *dev)\r
+{\r
+       return 0;\r
+}
+
+static int charge_current_enable(struct regulator_dev *dev)\r
+{\r
+       return 0;\r
+}
+
+static int charge_current_disable(struct regulator_dev *dev)\r
+{\r
+       return 0;\r
+}
+
+static int charge_get_current(struct regulator_dev *dev)\r
+{\r
+       const int *current_map = charge_current_map;\r
+\r
+       struct charge_platform_data *pdata = rdev_get_drvdata(dev);\r
+\r
+       gpio_direction_input(pdata->gpio_charge);\r
+          \r
+       return gpio_get_value(pdata->gpio_charge) ? current_map[0] *1000:current_map[1]*1000;\r
+}
+
+static int charge_set_current(struct regulator_dev *dev,\r
+                                 int min_uA, int max_uA)\r
+{\r
+       printk("enter charge_set_current , max_uA = %d\n",max_uA);\r
+       struct charge_platform_data *pdata = rdev_get_drvdata(dev);\r
+       const int *current_map = charge_current_map;\r
+       int max_mA = max_uA / 1000;\r
+       printk("charge_set_current:pdata->gpio_charge=%d\n",pdata->gpio_charge);\r
+       if ( max_mA == current_map[0] )\r
+            gpio_direction_output(pdata->gpio_charge, GPIO_HIGH);\r
+       else \r
+            gpio_direction_output(pdata->gpio_charge, GPIO_LOW);\r
+\r
+       return 0;\r
+\r
+}
+
+static struct regulator_ops charge_current_ops = {\r
+       .is_enabled = charge_current_is_enabled,\r
+       .enable = charge_current_enable,\r
+       .disable = charge_current_disable,\r
+       .get_current_limit = charge_get_current,\r
+       .set_current_limit = charge_set_current,\r
+};\r
+
+static struct regulator_desc chargeregulator= {\r
+               .name = "charge-regulator",\r
+               .ops = &charge_current_ops,\r
+               .type = REGULATOR_CURRENT,\r
+};
+
+\r
+
+static int __devinit charge_regulator_probe(struct platform_device *pdev)\r
+{\r
+\r
+       struct charge_platform_data *pdata = pdev->dev.platform_data;\r
+       struct regulator_dev *rdev;\r
+       int ret ;\r
+printk(KERN_INFO "enter charge regulator\n");\r
+#if 0\r
+       rdev = regulator_register(&chargeregulator, &pdev->dev,\r
+                               pdev->dev.platform_data, pdata);\r
+#else\r
+       rdev = regulator_register(&chargeregulator, &pdev->dev,\r
+                               pdata->init_data, pdata);\r
+#endif\r
+       if (IS_ERR(rdev)) {\r
+               dev_dbg(&pdev->dev, "couldn't register regulator\n");
+               return PTR_ERR(rdev);\r
+       }\r
+       \r
+       ret = gpio_request(pdata->gpio_charge, "charge_current");\r
+\r
+       if (ret) {\r
+                       dev_err(&pdev->dev,"failed to request charge gpio\n");\r
+                       goto err_gpio;\r
+               }\r
+\r
+       platform_set_drvdata(pdev, rdev);\r
+printk(KERN_INFO "charge_regulator: driver initialized\n");\r
+       return 0;\r
+       \r
+err_gpio:\r
+       gpio_free(pdata->gpio_charge);\r
+\r
+       return ret;\r
+\r
+}
+static int __devexit charge_regulator_remove(struct platform_device *pdev)\r
+{\r
+       struct charge_platform_data *pdata = pdev->dev.platform_data;\r
+       struct regulator_dev *rdev = platform_get_drvdata(pdev);\r
+\r
+       regulator_unregister(rdev);\r
+       gpio_free(pdata->gpio_charge);\r
+\r
+       return 0;\r
+}\r
+\r
+static struct platform_driver charge_regulator_driver = {\r
+       .driver = {\r
+               .name = "charge-regulator",\r
+       },\r
+       .remove = __devexit_p(charge_regulator_remove),\r
+};\r
+
+\r
+static int __init charge_regulator_module_init(void)\r
+{
+       return platform_driver_probe(&charge_regulator_driver, charge_regulator_probe);
+}
+
+static void __exit charge_regulator_module_exit(void)\r
+{
+       platform_driver_unregister(&charge_regulator_driver);\r
+}
+\r
+\r
+module_init(charge_regulator_module_init);\r
+\r
+module_exit(charge_regulator_module_exit);\r
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("hxy <hxy@rock-chips.com>");\r
+MODULE_DESCRIPTION("charge current change driver");\r
+\r
diff --git a/include/linux/regulator/charge-regulator.h b/include/linux/regulator/charge-regulator.h
new file mode 100644 (file)
index 0000000..d8969d7
--- /dev/null
@@ -0,0 +1,30 @@
+/* include/linux/regulator/charge-regulator.h\r
+ *\r
+ * Copyright (C) 2010 ROCKCHIP, Inc.\r
+ *\r
+ * This software is licensed under the terms of the GNU General Public\r
+ * License version 2, as published by the Free Software Foundation, and\r
+ * may be copied, distributed, and modified under those terms.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ */\r
+#ifndef __LINUX_REGULATOR_CHARGE_H\r
+\r
+#define __LINUX_REGULATOR_CHARGE_H\r
+
+#include <linux/regulator/machine.h>
+
+\r
+struct regulator_init_data;\r
+
+struct charge_platform_data {\r
+       int gpio_charge;\r
+       struct regulator_init_data *init_data;\r
+};
+
+#endif\r
+\r