rk30-pwm-regulator: use new pwm API

This commit is contained in:
黄涛
2013-01-04 18:29:20 +08:00
parent e79a54af92
commit 4c69fdc441
2 changed files with 56 additions and 196 deletions

View File

@@ -1,6 +1,6 @@
/* drivers/regulator/rk29-pwm-regulator.c
/*
*
* Copyright (C) 2010 ROCKCHIP, Inc.
* Copyright (C) 2013 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
@@ -12,17 +12,6 @@
* GNU General Public License for more details.
*
*/
/*******************************************************************/
/* COPYRIGHT (C) ROCK-CHIPS FUZHOU . ALL RIGHTS RESERVED. */
/*******************************************************************
FILE : rk29-pwm-regulator.c
DESC : rk29 pwm regulator driver
AUTHOR : hxy
DATE : 2010-12-20
NOTES :
$LOG: GPIO.C,V $
REVISION 0.01
********************************************************************/
#include <linux/bug.h>
#include <linux/err.h>
#include <linux/platform_device.h>
@@ -36,7 +25,7 @@ REVISION 0.01
#include <mach/iomux.h>
#include <linux/gpio.h>
#include <mach/board.h>
#include <plat/pwm.h>
#if 0
#define DBG(x...) printk(KERN_INFO x)
@@ -44,59 +33,33 @@ REVISION 0.01
#define DBG(x...)
#endif
#define PWM_VCORE_120 40
#define PWM_VCORE_125 32
#define PWM_VCORE_130 21
#define PWM_VCORE_135 10
#define PWM_VCORE_140 0
#define PWM_DCDC_MAX_NAME 2
struct rk_pwm_dcdc {
char name[PWM_DCDC_MAX_NAME];
char name[16];
struct regulator_desc desc;
int pwm_id;
struct clk *pwm_clk;
const void __iomem *pwm_base;
u32 suspend_hrc;
u32 suspend_lrc;
u32 backup_hrc;
u32 backup_lrc;
struct regulator_dev *regulator;
struct pwm_platform_data *pdata;
};
#if defined(CONFIG_ARCH_RK30)
#define pwm_write_reg(id, addr, val) __raw_writel(val, addr+(RK30_PWM01_BASE+(id>>1)*0x20000)+id*0x10)
#define pwm_read_reg(id, addr) __raw_readl(addr+(RK30_PWM01_BASE+(id>>1)*0x20000+id*0x10))
#elif defined(CONFIG_ARCH_RK29)
#define pwm_write_reg(id, addr, val) __raw_writel(val, addr+(RK29_PWM_BASE+id*0x10))
#define pwm_read_reg(id, addr) __raw_readl(addr+(RK29_PWM_BASE+id*0x10))
#elif defined(CONFIG_ARCH_RK2928)
#define pwm_write_reg(id, addr, val) __raw_writel(val, addr+(RK2928_PWM_BASE+id*0x10))
#define pwm_read_reg(id, addr) __raw_readl(addr+(RK2928_PWM_BASE+id*0x10))
#endif
const static int pwm_voltage_map[] = {
950000, 975000,1000000, 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000, 1325000, 1350000, 1375000, 1400000
};
static struct clk *pwm_clk[2];
static struct rk_pwm_dcdc *g_dcdc;
static int pwm_set_rate(struct pwm_platform_data *pdata,int nHz,u32 rate)
{
u32 divh,divTotal;
u32 lrc, hrc;
int id = pdata->pwm_id;
unsigned long clkrate;
#if defined(CONFIG_ARCH_RK29) || defined(CONFIG_ARCH_RK2928)
clkrate = clk_get_rate(pwm_clk[0]);
#elif defined(CONFIG_ARCH_RK30)
if (id == 0 || id == 1) {
clkrate = clk_get_rate(pwm_clk[0]);
} else if (id== 2 || id == 3) {
clkrate = clk_get_rate(pwm_clk[1]);
} else {
printk("%s:pwm id error,id=%d\n",__func__,id);
return -1;
}
#endif
clkrate = clk_get_rate(g_dcdc->pwm_clk);
DBG("%s:id=%d,rate=%d,clkrate=%d\n",__func__,id,rate,clkrate);
@@ -111,19 +74,16 @@ static int pwm_set_rate(struct pwm_platform_data *pdata,int nHz,u32 rate)
}
else if (rate < 100)
{
lrc = clkrate / nHz;
lrc = lrc >> (1+(PWM_DIV>>9));
lrc = lrc ? lrc : 1;
hrc = lrc * rate / 100;
hrc = hrc ? hrc : 1;
// iomux pwm
rk29_mux_api_set(pdata->pwm_iomux_name, pdata->pwm_iomux_pwm);
pwm_write_reg(id,PWM_REG_CTRL, PWM_DIV|PWM_RESET);
divh = clkrate / nHz;
divh = divh >> (1+(PWM_DIV>>9));
pwm_write_reg(id,PWM_REG_LRC,(divh == 0)?1:divh);
divTotal =pwm_read_reg(id,PWM_REG_LRC);
divh = divTotal*rate/100;
pwm_write_reg(id, PWM_REG_HRC, divh?divh:1);
pwm_write_reg(id,PWM_REG_CNTR,0);
pwm_write_reg(id, PWM_REG_CTRL,pwm_read_reg(id,PWM_REG_CTRL)|PWM_DIV|PWM_ENABLE|PWM_TimeEN);
rk_pwm_setup(id, PWM_DIV, hrc, lrc);
}
else if (rate == 100)
{
@@ -184,13 +144,8 @@ static int pwm_regulator_get_voltage(struct regulator_dev *dev)
return (dcdc->pdata->pwm_voltage);
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38))
static int pwm_regulator_set_voltage(struct regulator_dev *dev,
int min_uV, int max_uV, unsigned *selector)
#else
static int pwm_regulator_set_voltage(struct regulator_dev *dev,
int min_uV, int max_uV)
#endif
{
struct rk_pwm_dcdc *dcdc = rdev_get_drvdata(dev);
const int *voltage_map = dcdc->pdata->pwm_voltage_map;
@@ -227,9 +182,7 @@ static int pwm_regulator_set_voltage(struct regulator_dev *dev,
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38))
*selector = i;
#endif
DBG("%s:ok,vol=%d,pwm_value=%d\n",__FUNCTION__,vol,pwm_value);
@@ -246,12 +199,6 @@ static struct regulator_ops pwm_voltage_ops = {
.is_enabled = pwm_regulator_is_enabled,
};
static struct regulator_desc pwm_regulator= {
.name = "pwm-regulator",
.ops = &pwm_voltage_ops,
.type = REGULATOR_VOLTAGE,
};
static int __devinit pwm_regulator_probe(struct platform_device *pdev)
{
struct pwm_platform_data *pdata = pdev->dev.platform_data;
@@ -313,29 +260,33 @@ static int __devinit pwm_regulator_probe(struct platform_device *pdev)
dev_err(&pdev->dev,"failed to request pwm gpio\n");
goto err_gpio;
}
#if defined(CONFIG_ARCH_RK29)
pwm_clk[0] = clk_get(NULL, "pwm");
#elif defined(CONFIG_ARCH_RK30)
if (pwm_id == 0 || pwm_id == 1)
{
pwm_clk[0] = clk_get(NULL, "pwm01");
clk_enable(pwm_clk[0]);
}
else if (pwm_id== 2 || pwm_id == 3)
{
pwm_clk[1] = clk_get(NULL, "pwm23");
clk_enable(pwm_clk[1]);
}
#elif defined(CONFIG_ARCH_RK2928)
pwm_clk[0] = clk_get(NULL, "pwm01");
if (IS_ERR(pwm_clk[0])) {
printk("pwm_clk get error %p\n", pwm_clk[0]);
return -EINVAL;
}
clk_enable(pwm_clk[0]);
#endif
dcdc->pwm_clk = rk_pwm_get_clk(pwm_id);
dcdc->pwm_base = rk_pwm_get_base(pwm_id);
if (IS_ERR(dcdc->pwm_clk)) {
printk("pwm_clk get error %p\n", dcdc->pwm_clk);
return -EINVAL;
}
clk_enable(dcdc->pwm_clk);
dcdc->suspend_lrc = 0x25;
switch (pdata->suspend_voltage)
{
case 1000000:
default:
dcdc->suspend_hrc = 0x20;
break;
case 1050000:
dcdc->suspend_hrc = 0x1c;
break;
case 1100000:
dcdc->suspend_hrc = 0x18;
break;
case 1150000:
dcdc->suspend_hrc = 0x13;
break;
}
g_dcdc = dcdc;
platform_set_drvdata(pdev, dcdc);
printk(KERN_INFO "pwm_regulator.%d: driver initialized\n",id);
@@ -352,85 +303,26 @@ err:
}
static int __sramdata g_PWM_REG_LRC = 0;
static int __sramdata g_PWM_REG_HRC = 0;
void pwm_suspend_voltage(void)
{
struct rk_pwm_dcdc *dcdc = g_dcdc;
int suspend_voltage = 0;
int pwm_id = 0;
if(!dcdc)
return;
pwm_id = dcdc->pdata->pwm_id;
suspend_voltage = dcdc->pdata->suspend_voltage;
g_PWM_REG_LRC = pwm_read_reg(pwm_id, PWM_REG_LRC);
g_PWM_REG_HRC = pwm_read_reg(pwm_id,PWM_REG_HRC);
dcdc->backup_hrc = readl_relaxed(dcdc->pwm_base + PWM_REG_HRC);
dcdc->backup_lrc = readl_relaxed(dcdc->pwm_base + PWM_REG_LRC);
switch(suspend_voltage)
{
case 1000000:
pwm_write_reg(pwm_id, PWM_REG_LRC, 0x25);
pwm_write_reg(pwm_id,PWM_REG_HRC,0x20); // 1 .00
break;
case 1050000:
pwm_write_reg(pwm_id, PWM_REG_LRC, 0x25);
pwm_write_reg(pwm_id,PWM_REG_HRC,0x1c); // 1 .05
break;
case 1100000:
pwm_write_reg(pwm_id, PWM_REG_LRC, 0x25);
pwm_write_reg(pwm_id,PWM_REG_HRC,0x18); // 1 .1
break;
case 1150000:
pwm_write_reg(pwm_id, PWM_REG_LRC, 0x25);
pwm_write_reg(pwm_id,PWM_REG_HRC,0x13); // 1 .15
break;
default:
pwm_write_reg(pwm_id, PWM_REG_LRC, 0x25);
pwm_write_reg(pwm_id,PWM_REG_HRC,0x20); // 1 .00
break;
}
__rk_pwm_setup(dcdc->pwm_base, PWM_DIV, dcdc->suspend_hrc, dcdc->suspend_lrc);
}
void pwm_resume_voltage(void)
{
{
struct rk_pwm_dcdc *dcdc = g_dcdc;
int pwm_id = 0;
if(!dcdc)
return;
pwm_id = dcdc->pdata->pwm_id;
pwm_write_reg(pwm_id, PWM_REG_LRC, g_PWM_REG_LRC);
pwm_write_reg(pwm_id,PWM_REG_HRC, g_PWM_REG_HRC);
}
static int pwm_regulator_suspend(struct platform_device *pdev, pm_message_t state)
{
struct pwm_platform_data *pdata = pdev->dev.platform_data;
//struct rk_pwm_dcdc *dcdc = platform_get_drvdata(pdev);
//unsigned selector = 0;
//pwm_regulator_set_voltage(dcdc->regulator, 1100000, 1100000, &selector);
DBG("%s,pwm_id=%d\n",__func__,pdata->pwm_id);
return 0;
}
static int pwm_regulator_resume(struct platform_device *pdev)
{
struct pwm_platform_data *pdata = pdev->dev.platform_data;
//struct rk_pwm_dcdc *dcdc = platform_get_drvdata(pdev);
//unsigned selector = 0;
//pwm_regulator_set_voltage(dcdc->regulator, 1150000, 1150000, &selector);
DBG("%s,pwm_id=%d\n",__func__,pdata->pwm_id);
return 0;
__rk_pwm_setup(dcdc->pwm_base, PWM_DIV, dcdc->backup_hrc, dcdc->backup_lrc);
}
static int __devexit pwm_regulator_remove(struct platform_device *pdev)
@@ -448,8 +340,6 @@ static struct platform_driver pwm_regulator_driver = {
.driver = {
.name = "pwm-voltage-regulator",
},
.suspend = pwm_regulator_suspend,
.resume = pwm_regulator_resume,
.remove = __devexit_p(pwm_regulator_remove),
};
@@ -464,11 +354,6 @@ static void __exit pwm_regulator_module_exit(void)
platform_driver_unregister(&pwm_regulator_driver);
}
fs_initcall(pwm_regulator_module_init);
module_exit(pwm_regulator_module_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("hxy <hxy@rock-chips.com>");
MODULE_DESCRIPTION("k29 pwm change driver");

View File

@@ -15,40 +15,15 @@
#ifndef __LINUX_REGULATOR_PWM_H
#define __LINUX_REGULATOR_PWM_H
#include <linux/regulator/machine.h>
#define PWM_REG_CNTR 0x00
#define PWM_REG_HRC 0x04
#define PWM_REG_LRC 0x08
#define PWM_REG_CTRL 0x0c
#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)
#include <linux/regulator/machine.h>
#include <plat/pwm.h>
#define PWM_DIV PWM_DIV2
struct regulator_init_data;
struct pwm_platform_data {
int pwm_id;
int pwm_gpio;
@@ -63,7 +38,7 @@ struct pwm_platform_data {
int max_uV;
const int *pwm_voltage_map;
struct regulator_init_data *init_data;
};
};
#endif