aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/plat-s3c24xx/neo1973_pm_bt.c115
1 files changed, 57 insertions, 58 deletions
diff --git a/arch/arm/plat-s3c24xx/neo1973_pm_bt.c b/arch/arm/plat-s3c24xx/neo1973_pm_bt.c
index 894651afc12..217fcf05953 100644
--- a/arch/arm/plat-s3c24xx/neo1973_pm_bt.c
+++ b/arch/arm/plat-s3c24xx/neo1973_pm_bt.c
@@ -36,6 +36,8 @@
struct gta01_pm_bt_data {
struct regulator *regulator;
+ struct rfkill *rfkill;
+ int pre_resume_state;
};
static ssize_t bt_read(struct device *dev, struct device_attribute *attr,
@@ -72,11 +74,35 @@ static ssize_t bt_read(struct device *dev, struct device_attribute *attr,
}
}
+static void __gta02_pm_bt_toggle_radio(struct device *dev, unsigned int on)
+{
+ struct gta01_pm_bt_data *bt_data = dev_get_drvdata(dev);
+
+ dev_info(dev, "__gta02_pm_bt_toggle_radio %d\n", on);
+
+ if (machine_is_neo1973_gta02()) {
+
+ bt_data = dev_get_drvdata(dev);
+
+ neo1973_gpb_setpin(GTA02_GPIO_BT_EN, !on);
+
+ if (on) {
+ if (!regulator_is_enabled(bt_data->regulator))
+ regulator_enable(bt_data->regulator);
+ } else {
+ if (regulator_is_enabled(bt_data->regulator))
+ regulator_disable(bt_data->regulator);
+ }
+
+ neo1973_gpb_setpin(GTA02_GPIO_BT_EN, on);
+ }
+}
+
+
static int bt_rfkill_toggle_radio(void *data, enum rfkill_state state)
{
struct device *dev = data;
unsigned long on = (state == RFKILL_STATE_ON);
- struct gta01_pm_bt_data *bt_data;
if (machine_is_neo1973_gta01()) {
/* if we are powering up, assert reset, then power,
@@ -90,25 +116,8 @@ static int bt_rfkill_toggle_radio(void *data, enum rfkill_state state)
pcf50606_onoff_set(pcf50606_global,
PCF50606_REGULATOR_D1REG, on);
neo1973_gpb_setpin(GTA01_GPIO_BT_EN, on);
- } else if (machine_is_neo1973_gta02()) {
- if (s3c2410_gpio_getpin(GTA02_GPIO_BT_EN) == on)
- return 0;
-
- bt_data = dev_get_drvdata(dev);
- BUG_ON(!bt_data || !bt_data->regulator);
-
- neo1973_gpb_setpin(GTA02_GPIO_BT_EN, !on);
-
- if (on) {
- if (!regulator_is_enabled(bt_data->regulator))
- regulator_enable(bt_data->regulator);
- } else {
- if (regulator_is_enabled(bt_data->regulator))
- regulator_disable(bt_data->regulator);
- }
-
- neo1973_gpb_setpin(GTA02_GPIO_BT_EN, on);
- }
+ } else if (machine_is_neo1973_gta02())
+ __gta02_pm_bt_toggle_radio(dev, on);
return 0;
}
@@ -117,15 +126,12 @@ static ssize_t bt_write(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
unsigned long on = simple_strtoul(buf, NULL, 10);
- unsigned int vol;
- struct gta01_pm_bt_data *bt_data;
- struct regulator *regulator;
+ struct gta01_pm_bt_data *bt_data = dev_get_drvdata(dev);
if (!strcmp(attr->attr.name, "power_on")) {
- struct rfkill *rfkill = dev_get_drvdata(dev);
enum rfkill_state state = on ? RFKILL_STATE_ON : RFKILL_STATE_OFF;
bt_rfkill_toggle_radio(dev, state);
- rfkill->state = state;
+ bt_data->rfkill->state = state;
if (machine_is_neo1973_gta01()) {
/* if we are powering up, assert reset, then power,
@@ -139,29 +145,9 @@ static ssize_t bt_write(struct device *dev, struct device_attribute *attr,
pcf50606_onoff_set(pcf50606_global,
PCF50606_REGULATOR_D1REG, on);
neo1973_gpb_setpin(GTA01_GPIO_BT_EN, on);
- } else if (machine_is_neo1973_gta02()) {
- if (s3c2410_gpio_getpin(GTA02_GPIO_BT_EN) == on)
- return count;
-
- bt_data = dev_get_drvdata(dev);
- BUG_ON(!bt_data || !bt_data->regulator);
- regulator = bt_data->regulator;
-
- neo1973_gpb_setpin(GTA02_GPIO_BT_EN, !on);
-
- if (on) {
- if (!regulator_is_enabled(regulator))
- regulator_enable(regulator);
- } else {
- if (regulator_is_enabled(regulator))
- regulator_disable(regulator);
- }
-
- vol = regulator_get_voltage(regulator);
+ } else if (machine_is_neo1973_gta02())
+ __gta02_pm_bt_toggle_radio(dev, on);
- dev_info(dev, "GTA02 Set PCF50633 LDO4 = %d\n", vol);
- neo1973_gpb_setpin(GTA02_GPIO_BT_EN, on);
- }
} else if (!strcmp(attr->attr.name, "reset")) {
/* reset is low-active, so we need to invert */
if (machine_is_neo1973_gta01()) {
@@ -180,18 +166,29 @@ static DEVICE_ATTR(reset, 0644, bt_read, bt_write);
#ifdef CONFIG_PM
static int gta01_bt_suspend(struct platform_device *pdev, pm_message_t state)
{
+ struct gta01_pm_bt_data *bt_data = dev_get_drvdata(&pdev->dev);
+
dev_dbg(&pdev->dev, DRVMSG ": suspending\n");
- /* FIXME: The PMU should save the PMU status, and the GPIO code should
- * preserve the GPIO level, so there shouldn't be anything left to do
- * for us, should there? */
+
+ if (machine_is_neo1973_gta02()) {
+ bt_data->pre_resume_state =
+ s3c2410_gpio_getpin(GTA02_GPIO_BT_EN);
+ __gta02_pm_bt_toggle_radio(&pdev->dev, 0);
+ }
return 0;
}
static int gta01_bt_resume(struct platform_device *pdev)
{
+ struct gta01_pm_bt_data *bt_data = dev_get_drvdata(&pdev->dev);
dev_dbg(&pdev->dev, DRVMSG ": resuming\n");
+ if (machine_is_neo1973_gta02()) {
+ __gta02_pm_bt_toggle_radio(&pdev->dev,
+ bt_data->pre_resume_state);
+ }
+
return 0;
}
#else
@@ -219,6 +216,8 @@ static int __init gta01_bt_probe(struct platform_device *pdev)
dev_info(&pdev->dev, DRVMSG ": starting\n");
+ bt_data = kzalloc(sizeof(*bt_data), GFP_KERNEL);
+
if (machine_is_neo1973_gta01()) {
/* we make sure that the voltage is off */
pcf50606_onoff_set(pcf50606_global,
@@ -231,7 +230,6 @@ static int __init gta01_bt_probe(struct platform_device *pdev)
if (IS_ERR(regulator))
return -ENODEV;
- bt_data = kmalloc(sizeof(*bt_data), GFP_KERNEL);
bt_data->regulator = regulator;
dev_set_drvdata(&pdev->dev, bt_data);
@@ -264,24 +262,23 @@ static int __init gta01_bt_probe(struct platform_device *pdev)
return ret;
}
- platform_set_drvdata(pdev, rfkill);
+ bt_data->rfkill = rfkill;
return sysfs_create_group(&pdev->dev.kobj, &gta01_bt_attr_group);
}
static int gta01_bt_remove(struct platform_device *pdev)
{
- struct rfkill *rfkill = platform_get_drvdata(pdev);
-
- struct gta01_pm_bt_data *bt_data;
+ struct gta01_pm_bt_data *bt_data = dev_get_drvdata(&pdev->dev);
struct regulator *regulator;
sysfs_remove_group(&pdev->dev.kobj, &gta01_bt_attr_group);
- rfkill_unregister(rfkill);
- rfkill_free(rfkill);
+ if (bt_data->rfkill) {
+ rfkill_unregister(bt_data->rfkill);
+ rfkill_free(bt_data->rfkill);
+ }
- bt_data = dev_get_drvdata(&pdev->dev);
if (!bt_data || !bt_data->regulator)
return 0;
@@ -292,6 +289,8 @@ static int gta01_bt_remove(struct platform_device *pdev)
regulator_disable(regulator);
regulator_put(regulator);
+
+ kfree(bt_data);
return 0;
}