add pwm voltage regulator
authorhxy <hxy@rock-chips.com>
Tue, 21 Dec 2010 08:53:47 +0000 (16:53 +0800)
committerhxy <hxy@rock-chips.com>
Tue, 21 Dec 2010 08:53:47 +0000 (16:53 +0800)
arch/arm/mach-rk29/board-rk29sdk.c
arch/arm/mach-rk29/clock.c
drivers/regulator/Kconfig
drivers/regulator/Makefile
drivers/regulator/rk29-pwm-regulator.c [new file with mode: 0644]
include/linux/regulator/rk29-pwm-regulator.h [new file with mode: 0644]

index 75d110c50949a5852863c10d2270e57721c81c53..08d911a7225cbcc015bff13e6c11eeed8b78d961 100755 (executable)
@@ -43,6 +43,8 @@
 #include <media/soc_camera.h>                               /* ddl@rock-chips.com : camera support */
 #include <mach/vpu_mem.h>
 
+#include <linux/regulator/rk29-pwm-regulator.h>
+#include <linux/regulator/machine.h>
 
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
@@ -59,7 +61,7 @@
 #endif
 #define PMEM_GPU_SIZE       SZ_64M
 #define PMEM_UI_SIZE        SZ_32M
-#define PMEM_VPU_SIZE       SZ_64M
+#define PMEM_VPU_SIZE       SZ_32M
 #define PMEM_CAM_SIZE       0x00c00000
 #ifdef CONFIG_VIDEO_RK29_WORK_IPP
 #define MEM_CAMIPP_SIZE     SZ_4M
@@ -328,9 +330,9 @@ int p1003_init_platform_hw(void)
     }
     gpio_pull_updown(TOUCH_INT_PIN, 1);
     gpio_direction_output(TOUCH_RESET_PIN, 0);
-    msleep(500);
+    mdelay(500);
     gpio_set_value(TOUCH_RESET_PIN,GPIO_LOW);
-    msleep(500);
+    mdelay(500);
     gpio_set_value(TOUCH_RESET_PIN,GPIO_HIGH);
 
     return 0;
@@ -521,15 +523,6 @@ static struct i2c_board_info __initdata board_i2c1_devices[] = {
                .irq                    = RK29_PIN4_PA1,
        },
 #endif
-#if defined (CONFIG_ANX7150)
-       {
-               .type                   = "anx7150",
-               .addr           = 0x39,               //0x39, 0x3d
-               .flags                  = 0,
-               .irq                    = RK29_PIN1_PD7,
-       },
-#endif
-
 };
 #endif
 
@@ -849,6 +842,55 @@ struct rk29_bl_info rk29_bl_info = {
     .io_deinit = rk29_backlight_io_deinit,
 };
 #endif
+/*****************************************************************************************
+* pwm voltage regulator devices
+******************************************************************************************/
+#if defined (CONFIG_RK29_PWM_REGULATOR)
+
+#define REGULATOR_PWM_ID                                       2
+#define REGULATOR_PWM_MUX_NAME                 GPIO2A3_SDMMC0WRITEPRT_PWM2_NAME
+#define REGULATOR_PWM_MUX_MODE                                         GPIO2L_PWM2
+#define REGULATOR_PWM_MUX_MODE_GPIO                            GPIO2L_GPIO2A3
+#define REGULATOR_PWM_GPIO                             RK29_PIN2_PA3
+
+static struct regulator_consumer_supply pwm_consumers[] = {
+       {
+               .supply = "pwm-voltage",
+       }
+};
+
+static struct regulator_init_data rk29_pwm_regulator_data = {
+       .constraints = {
+               .name = "PWM2",
+               .min_uV = 1200000,
+               .max_uV = 1400000,
+               .apply_uV = 1,          
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,           
+       },
+       .num_consumer_supplies = ARRAY_SIZE(pwm_consumers),
+       .consumer_supplies = pwm_consumers,
+};
+
+static struct pwm_platform_data rk29_regulator_pwm_platform_data = {
+       .pwm_id = REGULATOR_PWM_ID,
+       .pwm_gpio = REGULATOR_PWM_GPIO,
+       //.pwm_iomux_name[] = REGULATOR_PWM_MUX_NAME;
+       .pwm_iomux_name = REGULATOR_PWM_MUX_NAME,
+       .pwm_iomux_pwm = REGULATOR_PWM_MUX_MODE,
+       .pwm_iomux_gpio = REGULATOR_PWM_MUX_MODE_GPIO,
+       .init_data  = &rk29_pwm_regulator_data,
+};
+
+static struct platform_device rk29_device_pwm_regulator = {
+       .name = "pwm-voltage-regulator",
+       .id   = -1,
+       .dev  = {
+               .platform_data = &rk29_regulator_pwm_platform_data,
+       },
+};
+
+#endif
+
 /*****************************************************************************************
  * SDMMC devices
 *****************************************************************************************/
@@ -1041,14 +1083,6 @@ static struct platform_device rk29sdk_wifi_device = {
 };
 #endif
 
-
-/* bluetooth rfkill device */
-static struct platform_device rk29sdk_rfkill = {
-        .name = "rk29sdk_rfkill",
-        .id = -1,
-};
-
-
 #ifdef CONFIG_VIVANTE
 static struct resource resources_gpu[] = {
     [0] = {
@@ -1143,19 +1177,18 @@ static void __init rk29_board_iomux_init(void)
        rk29_mux_api_set(GPIO0A7_MIIMDCLK_NAME, GPIO0L_MII_MDCLK);
        rk29_mux_api_set(GPIO0A6_MIIMD_NAME, GPIO0L_MII_MD);
        #endif
+       #ifdef CONFIG_RK29_PWM_REGULATOR
+       rk29_mux_api_set(REGULATOR_PWM_MUX_NAME,REGULATOR_PWM_MUX_MODE);
+       #endif
 }
 
 static struct platform_device *devices[] __initdata = {
 #ifdef CONFIG_UART1_RK29
        &rk29_device_uart1,
 #endif
-#ifdef CONFIG_UART0_RK29
-       &rk29_device_uart0,
-#endif
-#ifdef CONFIG_UART2_RK29
-       &rk29_device_uart2,
+#ifdef CONFIG_RK29_PWM_REGULATOR
+       &rk29_device_pwm_regulator,
 #endif
-
 #ifdef CONFIG_SPIM0_RK29
     &rk29xx_device_spi0m,
 #endif
@@ -1202,11 +1235,6 @@ static struct platform_device *devices[] __initdata = {
 #ifdef CONFIG_WIFI_CONTROL_FUNC
         &rk29sdk_wifi_device,
 #endif
-
-#ifdef CONFIG_BT
-        &rk29sdk_rfkill,
-#endif
-
 #ifdef CONFIG_MTD_NAND_RK29
        &rk29_device_nand,
 #endif
index 771f8215c20b3ad1514fdaf92782f50a8d4054a6..b13d61c351071b75f4bf982785fd44d5e991fbac 100755 (executable)
@@ -469,7 +469,7 @@ static int arm_pll_clk_set_rate(struct clk *clk, unsigned long rate)
                pt++;
        }
 
-       PWMInit(1 * MHZ, PWM_VCORE_135);        // 1.35V
+       PWMInit(1 * MHZ, PWM_VCORE_130);        // 1.30V
 
        /* make aclk safe & reparent to periph pll */
        cru_writel((cru_readl(CRU_CLKSEL0_CON) & ~(CORE_PARENT_MASK | CORE_ACLK_MASK)) | CORE_PARENT_PERIPH_PLL | CORE_ACLK_21, CRU_CLKSEL0_CON);
index b833192d75c26be890801b5b2a0e8d04d4b50c47..0b93f4ad25f44d6a6415c3a5ce7eea0eac0cba8d 100644 (file)
@@ -166,5 +166,9 @@ config RK2818_REGULATOR_LP8725
        depends on I2C
        help
          Say Y to enable support for the voltage regulators pmic lp8725 on the RK2818.
+config RK29_PWM_REGULATOR
+       tristate "rk2918 pwm voltage regulator"
+       help
+         Say Y to enable support for the voltage regulators charge on the RK2918.
 endif
 
index c19b61747f0bf595687a2c0fcc52a929df81f35e..77befcd24bf3338dc56041e9aed7bfe3a66c3513 100644 (file)
@@ -24,6 +24,7 @@ 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_RK29_PWM_REGULATOR) += rk29-pwm-regulator.o
 
 obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o
 obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o
diff --git a/drivers/regulator/rk29-pwm-regulator.c b/drivers/regulator/rk29-pwm-regulator.c
new file mode 100644 (file)
index 0000000..da22de5
--- /dev/null
@@ -0,0 +1,294 @@
+/* drivers/regulator/rk29-pwm-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           :               rk29-pwm-regulator.c\r
+DESC           :       rk29 pwm regulator driver\r
+AUTHOR         :       hxy\r
+DATE           :       2010-12-20\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>\r
+#include <linux/clk.h>\r
+#include <asm/io.h>\r
+#include <linux/delay.h>\r
+#include <linux/regulator/driver.h>
+#include <linux/regulator/rk29-pwm-regulator.h>\r
+#include <mach/iomux.h>\r
+#include <linux/gpio.h>\r
+
+
+#if 0
+#define DBG(x...)      printk(KERN_INFO x)
+#else
+#define DBG(x...)
+#endif
+\r
+\r
+#define        PWM_VCORE_120           40\r
+#define        PWM_VCORE_125           32\r
+#define        PWM_VCORE_130           21\r
+#define        PWM_VCORE_135           10\r
+#define        PWM_VCORE_140           0\r
+\r
+\r
+#define pwm_write_reg(id, addr, val)                   __raw_writel(val, addr+(RK29_PWM_BASE+id*0x10)) \r
+#define pwm_read_reg(id, addr)                         __raw_readl(addr+(RK29_PWM_BASE+id*0x10))\r
+\r
+\r
+const static int pwm_voltage_map[] = {\r
+       1200, 1250, 1300, 1350, 1400\r
+};\r
+\r
+static int pwm_set_rate(struct pwm_platform_data *pdata,int nHz,u32 rate)\r
+{\r
+    u32 divh,divTotal;\r
+    int id = pdata->pwm_id;\r
+    unsigned long clkrate;\r
+    struct clk *pwm_clk = clk_get(NULL, "pwm");\r
+\r
+    clkrate = clk_get_rate(pwm_clk);\r
+       \r
+    if ( id >3 || id <0 )\r
+       return -1;\r
+\r
+    if(rate == 0)\r
+       {\r
+        // iomux pwm2 to gpio2_a[3]     \r
+        rk29_mux_api_set(pdata->pwm_iomux_name, pdata->pwm_iomux_gpio);\r
+        // set gpio to low level        \r
+        gpio_set_value(pdata->pwm_gpio,GPIO_LOW);\r
+\r
+        pdata->pwm_voltage = 1400;\r
+        \r
+       }\r
+    else if (rate <= 100)\r
+       {\r
+        // iomux pwm2           \r
+        rk29_mux_api_set(pdata->pwm_iomux_name, pdata->pwm_iomux_pwm);\r
+                \r
+        pwm_write_reg(id,PWM_REG_CTRL, PWM_DIV|PWM_RESET);\r
+        divh = clkrate / nHz;\r
+        divh = divh >> (1+(PWM_DIV>>9));\r
+        pwm_write_reg(id,PWM_REG_LRC,(divh == 0)?1:divh);\r
+                \r
+        divTotal =pwm_read_reg(id,PWM_REG_LRC);\r
+        divh = divTotal*rate/100;\r
+        pwm_write_reg(id, PWM_REG_HRC, divh?divh:1);\r
+        pwm_write_reg(id,PWM_REG_CNTR,0);\r
+        pwm_write_reg(id, PWM_REG_CTRL,pwm_read_reg(id,PWM_REG_CTRL)|PWM_DIV|PWM_ENABLE|PWM_TimeEN);\r
+\r
+        pdata->pwm_voltage = 1400 - 476*rate/100;\r
+        \r
+       }\r
+     else\r
+       {\r
+       return -1;\r
+       }\r
+\r
+       msleep(50);\r
+       \r
+       \r
+    return (0);\r
+}\r
+\r
+static int pwm_init(struct pwm_platform_data *pdata, int nHz, int rate)\r
+{\r
+\r
+       struct clk *pwm_clk = clk_get(NULL, "pwm");\r
+          \r
+       // pwm2 clk enable\r
+       clk_enable(pwm_clk);\r
+\r
+       if(pwm_set_rate(pdata,nHz,rate)!=0)\r
+               return -1;              \r
+\r
+\r
+       return 0;\r
+}\r
+\r
+static int pwm_regulator_list_voltage(struct regulator_dev *dev,unsigned int index)\r
+{\r
+       int *pwm_voltage_table = pwm_voltage_map;\r
+
+       DBG("Enter %s, index =%d\n",__FUNCTION__,index);\r
+       if (index < sizeof(pwm_voltage_map)/sizeof(int))\r
+               return pwm_voltage_table[index];\r
+       else\r
+               return -1;\r
+}\r
+\r
+static int pwm_regulator_is_enabled(struct regulator_dev *dev)\r
+{\r
+       DBG("Enter %s\n",__FUNCTION__);\r
+       return 0;\r
+}
+
+static int pwm_regulator_enable(struct regulator_dev *dev)\r
+{\r
+       DBG("Enter %s\n",__FUNCTION__);\r
+       return 0;\r
+}
+
+static int pwm_regulator_disable(struct regulator_dev *dev)\r
+{\r
+       DBG("Enter %s\n",__FUNCTION__);\r
+       return 0;\r
+}
+
+static int pwm_regulator_get_voltage(struct regulator_dev *dev)\r
+{\r
+       struct pwm_platform_data *pdata = rdev_get_drvdata(dev);\r
+          \r
+       DBG("Enter %s\n",__FUNCTION__);  \r
+       \r
+       return (pdata->pwm_voltage*1000);\r
+}
+
+static int pwm_regulator_set_voltage(struct regulator_dev *dev,\r
+                                 int min_uV, int max_uV)\r
+{         \r
+       struct pwm_platform_data *pdata = rdev_get_drvdata(dev);\r
+       \r
+       const int *voltage_map = pwm_voltage_map;\r
+          \r
+       int min_mV = min_uV /1000, max_mA = max_uV / 1000;\r
+          \r
+       u32 size = sizeof(pwm_voltage_map)/sizeof(int), i, vol,pwm_value;\r
+\r
+       DBG("%s:  min_uV = %d, max_uV = %d\n",__FUNCTION__, min_uV,max_uV);\r
+\r
+       if (min_mV < voltage_map[0] ||max_mA > voltage_map[size-1])\r
+               return -EINVAL;
+          
+       for (i = 0; i < size; i++)\r
+       {\r
+               if (voltage_map[i] >= min_mV)\r
+                       break;
+       }\r
+
+\r
+       vol =  voltage_map[i];\r
+\r
+       pdata->pwm_voltage = vol;\r
+          \r
+       // VDD12 = 1.4 - 0.476*D , ÆäÖÐDΪPWMÕ¼¿Õ±È, \r
+       pwm_value = 100*(1400-vol)/476;  // pwm_value %\r
+\r
+          \r
+       if (pwm_set_rate(pdata,1000*1000,pwm_value)!=0)\r
+               return -1;\r
+\r
+       return 0;\r
+\r
+}
+
+static struct regulator_ops pwm_voltage_ops = {\r
+       .list_voltage   = pwm_regulator_list_voltage,\r
+       .set_voltage    =pwm_regulator_set_voltage,\r
+       .get_voltage    = pwm_regulator_get_voltage,\r
+       .enable         = pwm_regulator_enable,\r
+       .disable        = pwm_regulator_disable,\r
+       .is_enabled     = pwm_regulator_is_enabled,\r
+};\r
+
+static struct regulator_desc pwm_regulator= {\r
+               .name = "pwm-regulator",\r
+               .ops = &pwm_voltage_ops,\r
+               .type = REGULATOR_VOLTAGE,\r
+};\r
+
+static int __devinit pwm_regulator_probe(struct platform_device *pdev)\r
+{\r
+\r
+       struct pwm_platform_data *pdata = pdev->dev.platform_data;\r
+       struct regulator_dev *rdev;\r
+       int ret ;\r
+
+       rdev = regulator_register(&pwm_regulator, &pdev->dev,\r
+                               pdata->init_data, pdata);\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->pwm_gpio,"pwm");\r
+\r
+       if (ret) {\r
+                       dev_err(&pdev->dev,"failed to request pwm gpio\n");\r
+                       goto err_gpio;\r
+               }\r
+\r
+       //pwm_init(pdata,1000*1000,PWM_VCORE_130);\r
+       \r
+\r
+       platform_set_drvdata(pdev, rdev);\r
+       printk(KERN_INFO "pwm_regulator: driver initialized\n");\r
+\r
+       return 0;\r
+\r
+       \r
+err_gpio:\r
+       gpio_free(pdata->pwm_gpio);\r
+\r
+\r
+       return ret;\r
+\r
+}
+static int __devexit pwm_regulator_remove(struct platform_device *pdev)\r
+{\r
+       struct pwm_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->pwm_gpio);\r
+\r
+       return 0;\r
+}\r
+\r
+static struct platform_driver pwm_regulator_driver = {\r
+       .driver = {\r
+               .name = "pwm-voltage-regulator",\r
+       },\r
+       .remove = __devexit_p(pwm_regulator_remove),\r
+};\r
+
+\r
+static int __init pwm_regulator_module_init(void)\r
+{
+       return platform_driver_probe(&pwm_regulator_driver, pwm_regulator_probe);\r
+}
+
+static void __exit pwm_regulator_module_exit(void)\r
+{
+       platform_driver_unregister(&pwm_regulator_driver);\r
+}
+\r
+\r
+module_init(pwm_regulator_module_init);\r
+\r
+module_exit(pwm_regulator_module_exit);\r
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("hxy <hxy@rock-chips.com>");\r
+MODULE_DESCRIPTION("k29 pwm change driver");\r
diff --git a/include/linux/regulator/rk29-pwm-regulator.h b/include/linux/regulator/rk29-pwm-regulator.h
new file mode 100644 (file)
index 0000000..e0a0487
--- /dev/null
@@ -0,0 +1,64 @@
+/* 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_PWM_H\r
+\r
+#define __LINUX_REGULATOR_PWM_H\r
+
+#include <linux/regulator/machine.h>
+
+\r
+#define PWM_REG_CNTR           0x00\r
+#define PWM_REG_HRC            0x04 \r
+#define PWM_REG_LRC            0x08\r
+#define PWM_REG_CTRL           0x0c\r
+\r
+#define PWM_DIV2            (0<<9)
+#define PWM_DIV4            (1<<9)
+#define PWM_DIV8            (2<<9)
+#define PWM_DIV16           (3<<9)
+#define PWM_DIV32           (4<<9)
+#define PWM_DIV64           (5<<9)
+#define PWM_DIV128          (6<<9)
+#define PWM_DIV256          (7<<9)
+#define PWM_DIV512          (8<<9)
+#define PWM_DIV1024         (9<<9)
+
+#define PWM_CAPTURE         (1<<8)
+#define PWM_RESET           (1<<7)
+#define PWM_INTCLR          (1<<6)
+#define PWM_INTEN           (1<<5)
+#define PWM_SINGLE          (1<<6)
+
+#define PWM_ENABLE          (1<<3)
+#define PWM_TimeEN          (1)\r
+\r
+#define PWM_DIV              PWM_DIV2\r
+\r
+\r
+struct regulator_init_data;\r
+
+struct pwm_platform_data {\r
+       int     pwm_id;\r
+       int     pwm_gpio;\r
+       //char  pwm_iomux_name[50];\r
+       char*   pwm_iomux_name;\r
+       unsigned int    pwm_iomux_pwm;\r
+       int     pwm_iomux_gpio;\r
+       int     pwm_voltage;\r
+       struct regulator_init_data *init_data;\r
+};
+
+#endif\r
+\r