aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-s3c2410/include/mach/gta02.h3
-rw-r--r--arch/arm/mach-s3c2440/mach-gta02.c48
-rw-r--r--arch/arm/plat-s3c24xx/neo1973_pm_bt.c8
-rw-r--r--arch/arm/plat-s3c24xx/neo1973_pm_gps.c12
-rw-r--r--arch/arm/plat-s3c24xx/neo1973_pm_gsm.c4
-rw-r--r--arch/arm/plat-s3c24xx/neo1973_pm_host.c4
-rw-r--r--arch/arm/plat-s3c24xx/neo1973_pm_resume_reason.c2
-rw-r--r--drivers/i2c/chips/pcf50633.c307
-rw-r--r--include/linux/pcf50633.h6
9 files changed, 132 insertions, 262 deletions
diff --git a/arch/arm/mach-s3c2410/include/mach/gta02.h b/arch/arm/mach-s3c2410/include/mach/gta02.h
index 68f853ec2ac..7f103bd2912 100644
--- a/arch/arm/mach-s3c2410/include/mach/gta02.h
+++ b/arch/arm/mach-s3c2410/include/mach/gta02.h
@@ -3,6 +3,7 @@
#include <mach/regs-gpio.h>
#include <mach/irqs.h>
+#include <linux/pcf50633.h>
/* Different hardware revisions, passed in ATAG_REVISION by u-boot */
#define GTA02v1_SYSTEM_REV 0x00000310
@@ -106,4 +107,6 @@
int gta02_get_pcb_revision(void);
+extern struct pcf50633_platform_data gta02_pcf_pdata;
+
#endif /* _GTA02_H */
diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
index ac2e5b615ef..f0ecc641790 100644
--- a/arch/arm/mach-s3c2440/mach-gta02.c
+++ b/arch/arm/mach-s3c2440/mach-gta02.c
@@ -45,6 +45,8 @@
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
+#include <linux/i2c.h>
+
#include <linux/pcf50633.h>
#include <linux/lis302dl.h>
@@ -558,7 +560,7 @@ static struct platform_device gta02_pm_wlan_dev = {
.name = "gta02-pm-wlan",
};
-static struct pcf50633_platform_data gta02_pcf_pdata = {
+struct pcf50633_platform_data gta02_pcf_pdata = {
.used_features = PCF50633_FEAT_MBC |
PCF50633_FEAT_BBC |
PCF50633_FEAT_RTC |
@@ -740,23 +742,6 @@ static void mangle_pmu_pdata_by_system_rev(void)
}
}
-static struct resource gta02_pmu_resources[] = {
- [0] = {
- .flags = IORESOURCE_IRQ,
- .start = GTA02_IRQ_PCF50633,
- .end = GTA02_IRQ_PCF50633,
- },
-};
-
-struct platform_device gta02_pmu_dev = {
- .name = "pcf50633",
- .num_resources = ARRAY_SIZE(gta02_pmu_resources),
- .resource = gta02_pmu_resources,
- .dev = {
- .platform_data = &gta02_pcf_pdata,
- },
-};
-
#ifdef CONFIG_GTA02_HDQ
/* HDQ */
@@ -882,6 +867,14 @@ struct platform_device s3c24xx_pwm_device = {
.num_resources = 0,
};
+static struct i2c_board_info gta02_i2c_devs[] __initdata = {
+ {
+ I2C_BOARD_INFO("pcf50633", 0x73),
+ .irq = GTA02_IRQ_PCF50633,
+ .platform_data = &gta02_pcf_pdata,
+ },
+};
+
static struct s3c2410_nand_set gta02_nand_sets[] = {
[0] = {
.name = "neo1973-nand",
@@ -926,10 +919,10 @@ static void gta02_udc_command(enum s3c2410_udc_cmd_e cmd)
static void gta02_udc_vbus_draw(unsigned int ma)
{
- if (!pcf50633_global)
+ if (!gta02_pcf_pdata.pcf)
return;
- pcf50633_notify_usb_current_limit_change(pcf50633_global, ma);
+ pcf50633_notify_usb_current_limit_change(gta02_pcf_pdata.pcf, ma);
}
static struct s3c2410_udc_mach_info gta02_udc_cfg = {
@@ -977,7 +970,7 @@ static void gta02_jbt6k74_reset(int devidx, int level)
static void gta02_jbt6k74_resuming(int devidx)
{
- pcf50633_backlight_resume(pcf50633_global);
+ pcf50633_backlight_resume(gta02_pcf_pdata.pcf);
}
@@ -1323,7 +1316,7 @@ gta02_glamo_mmc_set_power(unsigned char power_mode, unsigned short vdd)
case MMC_POWER_ON:
case MMC_POWER_UP:
/* depend on pcf50633 driver init + not suspended */
- while (pcf50633_ready(pcf50633_global) && (timeout--))
+ while (pcf50633_ready(gta02_pcf_pdata.pcf) && (timeout--))
msleep(5);
if (timeout < 0) {
@@ -1335,9 +1328,9 @@ gta02_glamo_mmc_set_power(unsigned char power_mode, unsigned short vdd)
if (vdd > 7)
mv += 350 + 100 * (vdd - 8);
printk(KERN_INFO "SD power -> %dmV\n", mv);
- pcf50633_voltage_set(pcf50633_global,
+ pcf50633_voltage_set(gta02_pcf_pdata.pcf,
PCF50633_REGULATOR_HCLDO, mv);
- pcf50633_onoff_set(pcf50633_global,
+ pcf50633_onoff_set(gta02_pcf_pdata.pcf,
PCF50633_REGULATOR_HCLDO, 1);
break;
case MMC_POWER_OFF:
@@ -1346,9 +1339,9 @@ gta02_glamo_mmc_set_power(unsigned char power_mode, unsigned short vdd)
* the action then because pcf50633 suspend already
* dealt with it, otherwise we spin forever
*/
- if (pcf50633_ready(pcf50633_global))
+ if (pcf50633_ready(gta02_pcf_pdata.pcf))
return;
- pcf50633_onoff_set(pcf50633_global,
+ pcf50633_onoff_set(gta02_pcf_pdata.pcf,
PCF50633_REGULATOR_HCLDO, 0);
break;
}
@@ -1511,7 +1504,6 @@ static struct platform_device *gta02_devices[] __initdata = {
&s3c24xx_pwm_device,
&gta02_led_dev,
&gta02_pm_wlan_dev, /* not dependent on PMU */
- &gta02_pmu_dev,
&s3c_device_iis,
&s3c_device_i2c0,
@@ -1593,6 +1585,8 @@ static void __init gta02_machine_init(void)
mangle_glamo_res_by_system_rev();
+ i2c_register_board_info(0, gta02_i2c_devs, ARRAY_SIZE(gta02_i2c_devs));
+
mangle_pmu_pdata_by_system_rev();
platform_add_devices(gta02_devices, ARRAY_SIZE(gta02_devices));
diff --git a/arch/arm/plat-s3c24xx/neo1973_pm_bt.c b/arch/arm/plat-s3c24xx/neo1973_pm_bt.c
index 8be584c9f82..dc149ac6d02 100644
--- a/arch/arm/plat-s3c24xx/neo1973_pm_bt.c
+++ b/arch/arm/plat-s3c24xx/neo1973_pm_bt.c
@@ -88,11 +88,11 @@ static ssize_t bt_write(struct device *dev, struct device_attribute *attr,
if (s3c2410_gpio_getpin(GTA02_GPIO_BT_EN) == on)
return count;
neo1973_gpb_setpin(GTA02_GPIO_BT_EN, !on);
- pcf50633_voltage_set(pcf50633_global,
+ pcf50633_voltage_set(gta02_pcf_pdata.pcf,
PCF50633_REGULATOR_LDO4, on ? 3200 : 0);
- pcf50633_onoff_set(pcf50633_global,
+ pcf50633_onoff_set(gta02_pcf_pdata.pcf,
PCF50633_REGULATOR_LDO4, on);
- vol = pcf50633_voltage_get(pcf50633_global,
+ vol = pcf50633_voltage_get(gta02_pcf_pdata.pcf,
PCF50633_REGULATOR_LDO4);
dev_info(dev, "GTA02 Set PCF50633 LDO4 = %d\n", vol);
neo1973_gpb_setpin(GTA02_GPIO_BT_EN, on);
@@ -158,7 +158,7 @@ static int __init gta01_bt_probe(struct platform_device *pdev)
neo1973_gpb_setpin(GTA01_GPIO_BT_EN, 0);
} else if (machine_is_neo1973_gta02()) {
/* we make sure that the voltage is off */
- pcf50633_onoff_set(pcf50633_global,
+ pcf50633_onoff_set(gta02_pcf_pdata.pcf,
PCF50633_REGULATOR_LDO4, 0);
/* we pull reset to low to make sure that the chip doesn't
* drain power through the reset line */
diff --git a/arch/arm/plat-s3c24xx/neo1973_pm_gps.c b/arch/arm/plat-s3c24xx/neo1973_pm_gps.c
index 6fabf19d0da..a3a6ad3b53f 100644
--- a/arch/arm/plat-s3c24xx/neo1973_pm_gps.c
+++ b/arch/arm/plat-s3c24xx/neo1973_pm_gps.c
@@ -280,7 +280,7 @@ static void gps_pwron_set(int on)
if (machine_is_neo1973_gta02()) {
if (on) {
- pcf50633_voltage_set(pcf50633_global,
+ pcf50633_voltage_set(gta02_pcf_pdata.pcf,
PCF50633_REGULATOR_LDO5, 3000);
/* return UART pins to being UART pins */
s3c2410_gpio_cfgpin(S3C2410_GPH4, S3C2410_GPH4_TXD1);
@@ -296,7 +296,7 @@ static void gps_pwron_set(int on)
/* don't let RX from unpowered GPS float */
s3c2410_gpio_pullup(S3C2410_GPH5, 1);
}
- pcf50633_onoff_set(pcf50633_global,
+ pcf50633_onoff_set(gta02_pcf_pdata.pcf,
PCF50633_REGULATOR_LDO5, on);
}
}
@@ -307,7 +307,7 @@ static int gps_pwron_get(void)
return !!s3c2410_gpio_getpin(GTA01_GPIO_GPS_PWRON);
if (machine_is_neo1973_gta02())
- return !!pcf50633_onoff_get(pcf50633_global,
+ return !!pcf50633_onoff_get(gta02_pcf_pdata.pcf,
PCF50633_REGULATOR_LDO5);
return -1;
}
@@ -630,9 +630,9 @@ static int __init gta01_pm_gps_probe(struct platform_device *pdev)
case GTA02v4_SYSTEM_REV:
case GTA02v5_SYSTEM_REV:
case GTA02v6_SYSTEM_REV:
- pcf50633_voltage_set(pcf50633_global,
+ pcf50633_voltage_set(gta02_pcf_pdata.pcf,
PCF50633_REGULATOR_LDO5, 3000);
- pcf50633_onoff_set(pcf50633_global,
+ pcf50633_onoff_set(gta02_pcf_pdata.pcf,
PCF50633_REGULATOR_LDO5, 0);
dev_info(&pdev->dev, "FIC Neo1973 GPS Power Managerment:"
"starting\n");
@@ -659,7 +659,7 @@ static int gta01_pm_gps_remove(struct platform_device *pdev)
}
if (machine_is_neo1973_gta02()) {
- pcf50633_onoff_set(pcf50633_global, PCF50633_REGULATOR_LDO5, 0);
+ pcf50633_onoff_set(gta02_pcf_pdata.pcf, PCF50633_REGULATOR_LDO5, 0);
sysfs_remove_group(&pdev->dev.kobj, &gta02_gps_attr_group);
}
return 0;
diff --git a/arch/arm/plat-s3c24xx/neo1973_pm_gsm.c b/arch/arm/plat-s3c24xx/neo1973_pm_gsm.c
index 7dd28911904..ebed33558a7 100644
--- a/arch/arm/plat-s3c24xx/neo1973_pm_gsm.c
+++ b/arch/arm/plat-s3c24xx/neo1973_pm_gsm.c
@@ -117,7 +117,7 @@ static ssize_t gsm_write(struct device *dev, struct device_attribute *attr,
case GTA02v4_SYSTEM_REV:
case GTA02v5_SYSTEM_REV:
case GTA02v6_SYSTEM_REV:
- pcf50633_gpio_set(pcf50633_global,
+ pcf50633_gpio_set(gta02_pcf_pdata.pcf,
PCF50633_GPIO2, 1);
break;
}
@@ -134,7 +134,7 @@ static ssize_t gsm_write(struct device *dev, struct device_attribute *attr,
case GTA02v4_SYSTEM_REV:
case GTA02v5_SYSTEM_REV:
case GTA02v6_SYSTEM_REV:
- pcf50633_gpio_set(pcf50633_global,
+ pcf50633_gpio_set(gta02_pcf_pdata.pcf,
PCF50633_GPIO2, 0);
break;
}
diff --git a/arch/arm/plat-s3c24xx/neo1973_pm_host.c b/arch/arm/plat-s3c24xx/neo1973_pm_host.c
index bb25acdb7d2..8ab589b3ad8 100644
--- a/arch/arm/plat-s3c24xx/neo1973_pm_host.c
+++ b/arch/arm/plat-s3c24xx/neo1973_pm_host.c
@@ -27,7 +27,7 @@ static ssize_t pm_host_read(struct device *dev, struct device_attribute *attr,
char *buf)
{
return sprintf(buf, "%d\n",
- pcf50633_gpio_get(pcf50633_global, PCF50633_GPO));
+ pcf50633_gpio_get(gta02_pcf_pdata.pcf, PCF50633_GPO));
}
static ssize_t pm_host_write(struct device *dev, struct device_attribute *attr,
@@ -35,7 +35,7 @@ static ssize_t pm_host_write(struct device *dev, struct device_attribute *attr,
{
unsigned long on = simple_strtoul(buf, NULL, 10);
- pcf50633_gpio_set(pcf50633_global, PCF50633_GPO, on);
+ pcf50633_gpio_set(gta02_pcf_pdata.pcf, PCF50633_GPO, on);
return count;
}
diff --git a/arch/arm/plat-s3c24xx/neo1973_pm_resume_reason.c b/arch/arm/plat-s3c24xx/neo1973_pm_resume_reason.c
index c7730b60da9..a04466c8960 100644
--- a/arch/arm/plat-s3c24xx/neo1973_pm_resume_reason.c
+++ b/arch/arm/plat-s3c24xx/neo1973_pm_resume_reason.c
@@ -80,7 +80,7 @@ static ssize_t resume_reason_read(struct device *dev,
#ifdef CONFIG_MACH_NEO1973_GTA02
if ((gta) && (bit == 9)) /* PMU */
- end += pcf50633_report_resumers(pcf50633_global, end);
+ end += pcf50633_report_resumers(gta02_pcf_pdata.pcf, end);
#endif
}
diff --git a/drivers/i2c/chips/pcf50633.c b/drivers/i2c/chips/pcf50633.c
index 11a5f5a5b3a..8acb9a2a487 100644
--- a/drivers/i2c/chips/pcf50633.c
+++ b/drivers/i2c/chips/pcf50633.c
@@ -118,7 +118,7 @@ enum pcf50633_suspend_states {
struct pcf50633_data {
- struct i2c_client client;
+ struct i2c_client *client;
struct pcf50633_platform_data *pdata;
struct backlight_device *backlight;
struct mutex lock;
@@ -188,11 +188,6 @@ struct pcf50633_data {
static struct i2c_driver pcf50633_driver;
-struct pcf50633_data *pcf50633_global;
-EXPORT_SYMBOL_GPL(pcf50633_global);
-
-static struct platform_device *pcf50633_pdev;
-
static void pcf50633_usb_curlim_set(struct pcf50633_data *pcf, int ma);
static void pcf50633_charge_enable(struct pcf50633_data *pcf, int on);
@@ -204,10 +199,10 @@ static void pcf50633_charge_enable(struct pcf50633_data *pcf, int on);
static int __reg_write(struct pcf50633_data *pcf, u_int8_t reg, u_int8_t val)
{
if (pcf->suspend_state == PCF50633_SS_COMPLETED_SUSPEND) {
- dev_err(&pcf->client.dev, "__reg_write while suspended\n");
+ dev_err(&pcf->client->dev, "__reg_write while suspended\n");
dump_stack();
}
- return i2c_smbus_write_byte_data(&pcf->client, reg, val);
+ return i2c_smbus_write_byte_data(pcf->client, reg, val);
}
static int reg_write(struct pcf50633_data *pcf, u_int8_t reg, u_int8_t val)
@@ -226,10 +221,10 @@ static int32_t __reg_read(struct pcf50633_data *pcf, u_int8_t reg)
int32_t ret;
if (pcf->suspend_state == PCF50633_SS_COMPLETED_SUSPEND) {
- dev_err(&pcf->client.dev, "__reg_read while suspended\n");
+ dev_err(&pcf->client->dev, "__reg_read while suspended\n");
dump_stack();
}
- ret = i2c_smbus_read_byte_data(&pcf->client, reg);
+ ret = i2c_smbus_read_byte_data(pcf->client, reg);
return ret;
}
@@ -503,9 +498,9 @@ unsigned int pcf50633_voltage_get(struct pcf50633_data *pcf,
EXPORT_SYMBOL_GPL(pcf50633_voltage_get);
/* go into 'STANDBY' mode, i.e. power off the main CPU and peripherals */
-void pcf50633_go_standby(void)
+void pcf50633_go_standby(struct pcf50633_data *pcf)
{
- reg_set_bit_mask(pcf50633_global, PCF50633_REG_OOCSHDWN,
+ reg_set_bit_mask(pcf, PCF50633_REG_OOCSHDWN,
PCF50633_OOCSHDWN_GOSTDBY, PCF50633_OOCSHDWN_GOSTDBY);
}
EXPORT_SYMBOL_GPL(pcf50633_go_standby);
@@ -583,7 +578,7 @@ static void configure_pmu_for_charger(struct pcf50633_data *pcf,
* stop GPO / EN_HOSTUSB power driving out on the same
* USB power pins we have a 1A charger on right now!
*/
- dev_dbg(&pcf->client.dev, "Charger -> CHARGER_TYPE_1A\n");
+ dev_dbg(&pcf->client->dev, "Charger -> CHARGER_TYPE_1A\n");
__reg_write(pcf, PCF50633_GPO - PCF50633_GPIO1 +
PCF50633_REG_GPIO1CFG,
__reg_read(pcf, PCF50633_GPO - PCF50633_GPIO1 +
@@ -639,7 +634,7 @@ static void pcf50633_work_usbcurlim(struct work_struct *work)
(pcf->suspend_state == PCF50633_SS_COMPLETED_SUSPEND))
goto bail;
- dev_dbg(&pcf->client.dev, "pcf50633_work_usbcurlim\n");
+ dev_dbg(&pcf->client->dev, "pcf50633_work_usbcurlim\n");
if (!pcf->probe_completed)
goto reschedule;
@@ -659,7 +654,7 @@ static void pcf50633_work_usbcurlim(struct work_struct *work)
/* OK let's set the requested limit and finish */
- dev_dbg(&pcf->client.dev, "pcf50633_work_usbcurlim setting %dmA\n",
+ dev_dbg(&pcf->client->dev, "pcf50633_work_usbcurlim setting %dmA\n",
pcf->pending_curlimit);
pcf50633_usb_curlim_set(pcf, pcf->pending_curlimit);
@@ -668,9 +663,9 @@ bail:
return;
reschedule:
- dev_dbg(&pcf->client.dev, "pcf50633_work_usbcurlim rescheduling\n");
+ dev_dbg(&pcf->client->dev, "pcf50633_work_usbcurlim rescheduling\n");
if (!schedule_work(&pcf->work_usb_curlimit))
- dev_err(&pcf->client.dev, "curlim reschedule work "
+ dev_err(&pcf->client->dev, "curlim reschedule work "
"already queued\n");
mutex_unlock(&pcf->working_lock_usb_curlimit);
@@ -697,7 +692,7 @@ int pcf50633_notify_usb_current_limit_change(struct pcf50633_data *pcf,
return -EBUSY;
}
- dev_dbg(&pcf->client.dev,
+ dev_dbg(&pcf->client->dev,
"pcf50633_notify_usb_current_limit_change %dmA\n", ma);
/* prepare to detect USB power removal before we complete */
@@ -706,7 +701,7 @@ int pcf50633_notify_usb_current_limit_change(struct pcf50633_data *pcf,
pcf->pending_curlimit = ma;
if (!schedule_work(&pcf->work_usb_curlimit))
- dev_err(&pcf->client.dev, "curlim work item already queued\n");
+ dev_err(&pcf->client->dev, "curlim work item already queued\n");
return 0;
}
@@ -771,7 +766,7 @@ static void pcf50633_work(struct work_struct *work)
pcf->working = 1;
/* sanity */
- if (!&pcf->client.dev)
+ if (!&pcf->client->dev)
goto bail;
/*
@@ -808,19 +803,19 @@ static void pcf50633_work(struct work_struct *work)
goto reschedule;
/* this is the case early in resume! Sanity check! */
- if (i2c_get_clientdata(&pcf->client) == NULL)
+ if (i2c_get_clientdata(pcf->client) == NULL)
goto reschedule;
/*
* datasheet says we have to read the five IRQ
* status regs in one transaction
*/
- ret = i2c_smbus_read_i2c_block_data(&pcf->client,
+ ret = i2c_smbus_read_i2c_block_data(pcf->client,
PCF50633_REG_INT1,
sizeof(pcfirq),
pcfirq);
if (ret != sizeof(pcfirq)) {
- dev_info(&pcf->client.dev,
+ dev_info(&pcf->client->dev,
"Oh crap PMU IRQ register read failed -- "
"retrying later %d\n", ret);
/*
@@ -876,7 +871,7 @@ static void pcf50633_work(struct work_struct *work)
apm_queue_event(APM_POWER_STATUS_CHANGE);
pcf->flags |= PCF50633_F_USB_PRESENT;
if (pcf->pdata->cb)
- pcf->pdata->cb(&pcf->client.dev,
+ pcf->pdata->cb(&pcf->client->dev,
PCF50633_FEAT_MBC, PMU_EVT_USB_INSERT);
}
@@ -897,7 +892,7 @@ static void pcf50633_work(struct work_struct *work)
apm_queue_event(APM_POWER_STATUS_CHANGE);
pcf->flags |= PCF50633_F_CHG_PRESENT;
if (pcf->pdata->cb)
- pcf->pdata->cb(&pcf->client.dev,
+ pcf->pdata->cb(&pcf->client->dev,
PCF50633_FEAT_MBC, PMU_EVT_INSERT);
}
if (pcfirq[0] & PCF50633_INT1_ADPREM) {
@@ -907,7 +902,7 @@ static void pcf50633_work(struct work_struct *work)
apm_queue_event(APM_POWER_STATUS_CHANGE);
pcf->flags &= ~PCF50633_F_CHG_PRESENT;
if (pcf->pdata->cb)
- pcf->pdata->cb(&pcf->client.dev,
+ pcf->pdata->cb(&pcf->client->dev,
PCF50633_FEAT_MBC, PMU_EVT_REMOVE);
}
if (pcfirq[0] & PCF50633_INT1_USBINS) {
@@ -916,7 +911,7 @@ static void pcf50633_work(struct work_struct *work)
apm_queue_event(APM_POWER_STATUS_CHANGE);
pcf->flags |= PCF50633_F_USB_PRESENT;
if (pcf->pdata->cb)
- pcf->pdata->cb(&pcf->client.dev,
+ pcf->pdata->cb(&pcf->client->dev,
PCF50633_FEAT_MBC, PMU_EVT_USB_INSERT);
msleep(500); /* debounce, allow to see any ID resistor */
/* completion irq will figure out our charging stance */
@@ -939,7 +934,7 @@ static void pcf50633_work(struct work_struct *work)
pcf->flags &= ~PCF50633_F_USB_PRESENT;
if (pcf->pdata->cb)
- pcf->pdata->cb(&pcf->client.dev,
+ pcf->pdata->cb(&pcf->client->dev,
PCF50633_FEAT_MBC, PMU_EVT_USB_REMOVE);
/* destroy any memory of grant of power from host */
@@ -989,7 +984,7 @@ static void pcf50633_work(struct work_struct *work)
if (pcf->onkey_seconds >=
pcf->pdata->onkey_seconds_shutdown) {
DEBUGPC("Power Off ");
- pcf50633_go_standby();
+ pcf50633_go_standby(pcf);
}
}
}
@@ -1050,7 +1045,7 @@ static void pcf50633_work(struct work_struct *work)
ret);
} else {
if (pcf->pdata->cb)
- pcf->pdata->cb(&pcf->client.dev,
+ pcf->pdata->cb(&pcf->client->dev,
PCF50633_FEAT_MBC, PMU_EVT_CHARGER_IDLE);
}
@@ -1063,33 +1058,33 @@ static void pcf50633_work(struct work_struct *work)
* appear with no battery attached
*/
if (pcf->pdata->cb)
- pcf->pdata->cb(&pcf->client.dev,
+ pcf->pdata->cb(&pcf->client->dev,
PCF50633_FEAT_MBC, PMU_EVT_CHARGER_CHANGE);
}
if (pcfirq[2] & PCF50633_INT3_THLIMON) {
DEBUGPC("THLIMON ");
pcf->flags |= PCF50633_F_CHG_PROT;
if (pcf->pdata->cb)
- pcf->pdata->cb(&pcf->client.dev,
+ pcf->pdata->cb(&pcf->client->dev,
PCF50633_FEAT_MBC, PMU_EVT_CHARGER_CHANGE);
}
if (pcfirq[2] & PCF50633_INT3_THLIMOFF) {
DEBUGPC("THLIMOFF ");
pcf->flags &= ~PCF50633_F_CHG_PROT;
if (pcf->pdata->cb)
- pcf->pdata->cb(&pcf->client.dev,
+ pcf->pdata->cb(&pcf->client->dev,
PCF50633_FEAT_MBC, PMU_EVT_CHARGER_CHANGE);
}
if (pcfirq[2] & PCF50633_INT3_USBLIMON) {
DEBUGPC("USBLIMON ");
if (pcf->pdata->cb)
- pcf->pdata->cb(&pcf->client.dev,
+ pcf->pdata->cb(&pcf->client->dev,
PCF50633_FEAT_MBC, PMU_EVT_CHARGER_CHANGE);
}
if (pcfirq[2] & PCF50633_INT3_USBLIMOFF) {
DEBUGPC("USBLIMOFF ");
if (pcf->pdata->cb)
- pcf->pdata->cb(&pcf->client.dev,
+ pcf->pdata->cb(&pcf->client->dev,
PCF50633_FEAT_MBC, PMU_EVT_CHARGER_CHANGE);
}
if (pcfirq[2] & PCF50633_INT3_ADCRDY) {
@@ -1137,7 +1132,7 @@ static void pcf50633_work(struct work_struct *work)
* we are not actually charging anything
*/
if (pcf->pdata->cb)
- pcf->pdata->cb(&pcf->client.dev,
+ pcf->pdata->cb(&pcf->client->dev,
PCF50633_FEAT_MBC, PMU_EVT_CHARGER_IDLE);
reg_set_bit_mask(pcf, PCF50633_REG_MBCC1,
@@ -1229,7 +1224,7 @@ static void pcf50633_work(struct work_struct *work)
bail:
pcf->working = 0;
input_sync(pcf->input_dev);
- put_device(&pcf->client.dev);
+ put_device(&pcf->client->dev);
mutex_unlock(&pcf->working_lock);
return;
@@ -1242,10 +1237,10 @@ reschedule:
if ((pcf->suspend_state != PCF50633_SS_STARTING_SUSPEND) &&
(pcf->suspend_state != PCF50633_SS_COMPLETED_SUSPEND)) {
msleep(10);
- dev_dbg(&pcf->client.dev, "rescheduling interrupt service\n");
+ dev_dbg(&pcf->client->dev, "rescheduling interrupt service\n");
}
if (!schedule_work(&pcf->work))
- dev_err(&pcf->client.dev, "int service reschedule failed\n");
+ dev_err(&pcf->client->dev, "int service reschedule failed\n");
/* we don't put the device here, hold it for next time */
mutex_unlock(&pcf->working_lock);
@@ -1256,11 +1251,11 @@ static irqreturn_t pcf50633_irq(int irq, void *_pcf)
struct pcf50633_data *pcf = _pcf;
DEBUGP("entering(irq=%u, pcf=%p): scheduling work\n", irq, _pcf);
- dev_dbg(&pcf->client.dev, "pcf50633_irq scheduling work\n");
+ dev_dbg(&pcf->client->dev, "pcf50633_irq scheduling work\n");
- get_device(&pcf->client.dev);
+ get_device(&pcf->client->dev);
if (!schedule_work(&pcf->work) && !pcf->working)
- dev_err(&pcf->client.dev, "pcf irq work already queued\n");
+ dev_err(&pcf->client->dev, "pcf irq work already queued\n");
return IRQ_HANDLED;
}
@@ -1420,7 +1415,7 @@ static void pcf50633_usb_curlim_set(struct pcf50633_data *pcf, int ma)
pcf->last_curlim_set = ma;
- dev_dbg(&pcf->client.dev, "setting usb current limit to %d ma", ma);
+ dev_dbg(&pcf->client->dev, "setting usb current limit to %d ma", ma);
if (ma >= 1000) {
bits = PCF50633_MBCC7_USB_1000mA;
@@ -1445,7 +1440,7 @@ static void pcf50633_usb_curlim_set(struct pcf50633_data *pcf, int ma)
break;
default: /* right charging context that if there is power, we charge */
if (pcf->flags & PCF50633_F_USB_PRESENT)
- pcf->pdata->cb(&pcf->client.dev,
+ pcf->pdata->cb(&pcf->client->dev,
PCF50633_FEAT_MBC, PMU_EVT_CHARGER_ACTIVE);
break;
}
@@ -1453,7 +1448,7 @@ static void pcf50633_usb_curlim_set(struct pcf50633_data *pcf, int ma)
* enable or disable charging according to current limit -- this will
* also throw a platform notification callback about it
*/
- pcf50633_charge_enable(pcf50633_global, active);
+ pcf50633_charge_enable(pcf, active);
/* clear batfull */
reg_set_bit_mask(pcf, PCF50633_REG_MBCC1,
@@ -1511,7 +1506,7 @@ static void pcf50633_charge_enable(struct pcf50633_data *pcf, int on)
case PCF50633_MBCC7_USB_500mA:
if (pcf->flags & PCF50633_F_USB_PRESENT)
if (pcf->pdata->cb)
- pcf->pdata->cb(&pcf->client.dev,
+ pcf->pdata->cb(&pcf->client->dev,
PCF50633_FEAT_MBC,
PMU_EVT_CHARGER_ACTIVE);
break;
@@ -1522,7 +1517,7 @@ static void pcf50633_charge_enable(struct pcf50633_data *pcf, int on)
pcf->flags &= ~PCF50633_F_CHG_ENABLED;
bits = 0;
if (pcf->pdata->cb)
- pcf->pdata->cb(&pcf->client.dev,
+ pcf->pdata->cb(&pcf->client->dev,
PCF50633_FEAT_MBC, PMU_EVT_CHARGER_IDLE);
}
reg_set_bit_mask(pcf, PCF50633_REG_MBCC1, PCF50633_MBCC1_CHGENA,
@@ -1637,47 +1632,6 @@ static ssize_t show_chgstate(struct device *dev, struct device_attribute *attr,
static DEVICE_ATTR(chgstate, S_IRUGO | S_IWUSR, show_chgstate, NULL);
/***********************************************************************
- * APM emulation
- ***********************************************************************/
-
-extern void (*apm_get_power_status)(struct apm_power_info *);
-
-static void pcf50633_get_power_status(struct apm_power_info *info)
-{
- struct pcf50633_data *pcf = pcf50633_global;
- u_int8_t chgmod = reg_read(pcf, PCF50633_REG_MBCS2) &
- PCF50633_MBCS2_MBC_MASK;
-
- u_int16_t battvolt = pcf50633_battvolt(pcf);
-
- if (reg_read(pcf, PCF50633_REG_MBCS1) &
- (PCF50633_MBCS1_USBPRES|PCF50633_MBCS1_ADAPTPRES))
- info->ac_line_status = APM_AC_ONLINE;
- else
- info->ac_line_status = APM_AC_OFFLINE;
-
- switch (chgmod) {
- case PCF50633_MBCS2_MBC_PLAY:
- case PCF50633_MBCS2_MBC_USB_PRE:
- case PCF50633_MBCS2_MBC_USB_PRE_WAIT:
- case PCF50633_MBCS2_MBC_USB_FAST_WAIT:
- case PCF50633_MBCS2_MBC_ADP_PRE:
- case PCF50633_MBCS2_MBC_ADP_PRE_WAIT:
- case PCF50633_MBCS2_MBC_ADP_FAST_WAIT:
- case PCF50633_MBCS2_MBC_BAT_FULL:
- case PCF50633_MBCS2_MBC_HALT:
- info->battery_life = battvolt_scale(battvolt);
- break;
- case PCF50633_MBCS2_MBC_USB_FAST:
- case PCF50633_MBCS2_MBC_ADP_FAST:
- info->battery_status = APM_BATTERY_STATUS_CHARGING;
- info->battery_flag = APM_BATTERY_FLAG_CHARGING;
- default:
- break;
- }
-}
-
-/***********************************************************************
* RTC
***********************************************************************/
enum pcf50633_time_indexes {
@@ -1758,7 +1712,7 @@ static int pcf50633_rtc_read_time(struct device *dev, struct rtc_time *tm)
mutex_lock(&pcf->lock);
- ret = i2c_smbus_read_i2c_block_data(&pcf->client,
+ ret = i2c_smbus_read_i2c_block_data(pcf->client,
PCF50633_REG_RTCSC,
PCF50633_TI_EXTENT,
&pcf_tm.time[0]);
@@ -1806,7 +1760,7 @@ static int pcf50633_rtc_set_time(struct device *dev, struct rtc_time *tm)
mutex_lock(&pcf->lock);
/* FIXME: disable second interrupt */
- ret = i2c_smbus_write_i2c_block_data(&pcf->client,
+ ret = i2c_smbus_write_i2c_block_data(pcf->client,
PCF50633_REG_RTCSC,
PCF50633_TI_EXTENT,
&pcf_tm.time[0]);
@@ -1831,7 +1785,7 @@ static int pcf50633_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
alrm->enabled =
__reg_read(pcf, PCF50633_REG_INT1M) & PCF50633_INT1_ALARM ? 0 : 1;
- ret = i2c_smbus_read_i2c_block_data(&pcf->client,
+ ret = i2c_smbus_read_i2c_block_data(pcf->client,
PCF50633_REG_RTCSCA,
PCF50633_TI_EXTENT,
&pcf_tm.time[0]);
@@ -1862,7 +1816,7 @@ static int pcf50633_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
irqmask |= PCF50633_INT1_ALARM;
__reg_write(pcf, PCF50633_REG_INT1M, irqmask);
- ret = i2c_smbus_write_i2c_block_data(&pcf->client,
+ ret = i2c_smbus_write_i2c_block_data(pcf->client,
PCF50633_REG_RTCSCA,
PCF50633_TI_EXTENT,
&pcf_tm.time[0]);
@@ -2113,38 +2067,23 @@ static void populate_sysfs_group(struct pcf50633_data *pcf)
}
-static int pcf50633_detect(struct i2c_adapter *adapter, int address, int kind)
+static int pcf50633_probe(struct i2c_client *client, const struct i2c_device_id *ids)
{
- struct i2c_client *new_client;
struct pcf50633_data *pcf;
+ struct pcf50633_platform_data *pdata;
int err = 0;
int irq;
- printk(KERN_INFO "************ pcf50633_detect\n");
+ DEBUGP("entering probe\n");
- DEBUGP("entering\n");
- if (!pcf50633_pdev) {
- printk(KERN_ERR "pcf50633: driver needs a platform_device!\n");
- return -EIO;
- }
-
- irq = platform_get_irq(pcf50633_pdev, 0);
- if (irq < 0) {
- dev_err(&pcf50633_pdev->dev, "no irq in platform resources!\n");
- return -EIO;
- }
-
- /* At the moment, we only support one PCF50633 in a system */
- if (pcf50633_global) {
- dev_err(&pcf50633_pdev->dev,
- "currently only one chip supported\n");
- return -EBUSY;
- }
+ pdata = client->dev.platform_data;
pcf = kzalloc(sizeof(*pcf), GFP_KERNEL);
if (!pcf)
- return -ENOMEM;
+ return -ENOMEM;
+ i2c_set_clientdata(client, pcf);
+ irq = client->irq;
mutex_init(&pcf->lock);
mutex_init(&pcf->working_lock);
mutex_init(&pcf->working_lock_nobat);
@@ -2152,41 +2091,28 @@ static int pcf50633_detect(struct i2c_adapter *adapter, int address, int kind)
INIT_WORK(&pcf->work, pcf50633_work);
INIT_WORK(&pcf->work_nobat, pcf50633_work_nobat);
INIT_WORK(&pcf->work_usb_curlimit, pcf50633_work_usbcurlim);
+
+ pcf->client = client;
pcf->irq = irq;
pcf->working = 0;
pcf->suppress_onkey_events = 0;
pcf->onkey_seconds = -1;
- pcf->pdata = pcf50633_pdev->dev.platform_data;
-
- new_client = &pcf->client;
- i2c_set_clientdata(new_client, pcf);
- new_client->addr = address;
- new_client->adapter = adapter;
- new_client->driver = &pcf50633_driver;
- new_client->flags = 0;
- strlcpy(new_client->name, "pcf50633", I2C_NAME_SIZE);
-
- /* now we try to detect the chip */
-
- /* register with i2c core */
- if ((err = i2c_attach_client(new_client))) {
- dev_err(&new_client->dev,
- "error during i2c_attach_client()\n");
- goto exit_free;
- }
+ pcf->pdata = pdata;
+
+ /* FIXME: now we try to detect the chip */
populate_sysfs_group(pcf);
- err = sysfs_create_group(&new_client->dev.kobj, &pcf_attr_group);
+ err = sysfs_create_group(&client->dev.kobj, &pcf_attr_group);
if (err) {
- dev_err(&new_client->dev, "error creating sysfs group\n");
- goto exit_detach;
+ dev_err(&client->dev, "error creating sysfs group\n");
+ goto exit_free;
}
/* create virtual charger 'device' */
/* register power off handler with core power management */
- pm_power_off = &pcf50633_go_standby;
+ /* FIXME : pm_power_off = &pcf50633_go_standby; */
pcf->input_dev = input_allocate_device();
if (!pcf->input_dev)
@@ -2234,11 +2160,11 @@ static int pcf50633_detect(struct i2c_adapter *adapter, int address, int kind)
goto exit_input;
if (enable_irq_wake(irq) < 0)
- dev_err(&new_client->dev, "IRQ %u cannot be enabled as wake-up"
+ dev_err(&client->dev, "IRQ %u cannot be enabled as wake-up"
"source in this hardware revision!", irq);
if (pcf->pdata->used_features & PCF50633_FEAT_RTC) {
- pcf->rtc = rtc_device_register("pcf50633", &new_client->dev,
+ pcf->rtc = rtc_device_register("pcf50633", &client->dev,
&pcf50633_rtc_ops, THIS_MODULE);
if (IS_ERR(pcf->rtc)) {
err = PTR_ERR(pcf->rtc);
@@ -2248,7 +2174,7 @@ static int pcf50633_detect(struct i2c_adapter *adapter, int address, int kind)
if (pcf->pdata->used_features & PCF50633_FEAT_PWM_BL) {
pcf->backlight = backlight_device_register("pcf50633-bl",
- &new_client->dev,
+ &client->dev,
pcf,
&pcf50633bl_ops);
if (!pcf->backlight)
@@ -2263,45 +2189,36 @@ static int pcf50633_detect(struct i2c_adapter *adapter, int address, int kind)
}
if (pcf->pdata->flag_use_apm_emulation)
- apm_get_power_status = pcf50633_get_power_status;
+ apm_get_power_status = NULL;
+ pdata->pcf = pcf;
pcf->probe_completed = 1;
- pcf50633_global = pcf;
- dev_info(&new_client->dev, "probe completed\n");
+ dev_info(&client->dev, "probe completed\n");
/* if platform was interested, give him a chance to register
* platform devices that switch power with us as the parent
* at registration time -- ensures suspend / resume ordering
*/
if (pcf->pdata->attach_child_devices)
- (pcf->pdata->attach_child_devices)(&new_client->dev);
+ (pcf->pdata->attach_child_devices)(&client->dev);
return 0;
exit_rtc:
if (pcf->pdata->used_features & PCF50633_FEAT_RTC)
- rtc_device_unregister(pcf50633_global->rtc);
+ rtc_device_unregister(pcf->rtc);
exit_irq:
- free_irq(pcf50633_global->irq, pcf50633_global);
+ free_irq(pcf->irq, pcf);
exit_input:
input_unregister_device(pcf->input_dev);
exit_sysfs:
pm_power_off = NULL;
- sysfs_remove_group(&new_client->dev.kobj, &pcf_attr_group);
-exit_detach:
- i2c_detach_client(new_client);
+ sysfs_remove_group(&client->dev.kobj, &pcf_attr_group);
exit_free:
kfree(pcf);
- pcf50633_global = NULL;
return err;
}
-static int pcf50633_attach_adapter(struct i2c_adapter *adapter)
-{
- printk(KERN_ERR "**** entering pcf50633_attach_adapter, calling i2c_probe\n");
- return i2c_probe(adapter, &addr_data, &pcf50633_detect);
-}
-
-static int pcf50633_detach_client(struct i2c_client *client)
+static int pcf50633_remove(struct i2c_client *client)
{
struct pcf50633_data *pcf = i2c_get_clientdata(client);
@@ -2430,7 +2347,7 @@ static int pcf50633_suspend(struct device *dev, pm_message_t state)
/* Save all registers that don't "survive" standby state */
pcf->standby_regs.ooctim2 = __reg_read(pcf, PCF50633_REG_OOCTIM2);
- ret = i2c_smbus_read_i2c_block_data(&pcf->client,
+ ret = i2c_smbus_read_i2c_block_data(pcf->client,
PCF50633_REG_AUTOOUT,
sizeof(pcf->standby_regs.misc),
&pcf->standby_regs.misc[0]);
@@ -2438,7 +2355,7 @@ static int pcf50633_suspend(struct device *dev, pm_message_t state)
dev_err(dev, "Failed to save misc levels and enables :-(\n");
/* regulator voltages and enable states */
- ret = i2c_smbus_read_i2c_block_data(&pcf->client,
+ ret = i2c_smbus_read_i2c_block_data(pcf->client,
PCF50633_REG_LDO1OUT,
sizeof(pcf->standby_regs.ldo),
&pcf->standby_regs.ldo[0]);
@@ -2477,7 +2394,7 @@ static int pcf50633_suspend(struct device *dev, pm_message_t state)
for (i = 0; i < 5; i++)
res[i] = ~pcf->pdata->resumers[i];
- ret = i2c_smbus_write_i2c_block_data(&pcf->client,
+ ret = i2c_smbus_write_i2c_block_data(pcf->client,
PCF50633_REG_INT1M,
5, &res[0]);
if (ret)
@@ -2537,8 +2454,7 @@ EXPORT_SYMBOL_GPL(pcf50633_wait_for_ready);
void pcf50633_backlight_resume(struct pcf50633_data *pcf)
{
- dev_err(&pcf->client.dev, "pcf50633_backlight_resume\n");
-
+ dev_err(&pcf->client->dev, "pcf50633_backlight_resume\n");
reg_write(pcf, PCF50633_REG_LEDENA, 0x00);
reg_write(pcf, PCF50633_REG_LEDDIM, 0x01);
reg_write(pcf, PCF50633_REG_LEDENA, 0x01);
@@ -2581,7 +2497,7 @@ static int pcf50633_resume(struct device *dev)
}
/* regulator voltages and enable states */
- ret = i2c_smbus_write_i2c_block_data(&pcf->client,
+ ret = i2c_smbus_write_i2c_block_data(pcf->client,
PCF50633_REG_AUTOOUT,
sizeof(misc),
&misc[0]);
@@ -2593,7 +2509,7 @@ static int pcf50633_resume(struct device *dev)
pcf50633_backlight_resume(pcf);
/* regulator voltages and enable states */
- ret = i2c_smbus_write_i2c_block_data(&pcf->client,
+ ret = i2c_smbus_write_i2c_block_data(pcf->client,
PCF50633_REG_LDO1OUT,
sizeof(pcf->standby_regs.ldo),
&pcf->standby_regs.ldo[0]);
@@ -2603,7 +2519,7 @@ static int pcf50633_resume(struct device *dev)
memset(res, 0, sizeof(res));
/* not interested in second on resume */
res[0] = PCF50633_INT1_SECOND;
- ret = i2c_smbus_write_i2c_block_data(&pcf->client,
+ ret = i2c_smbus_write_i2c_block_data(pcf->client,
PCF50633_REG_INT1M,
5, &res[0]);
if (ret)
@@ -2621,7 +2537,7 @@ static int pcf50633_resume(struct device *dev)
* case nothing is waiting for service, no harm done.
*/
- get_device(&pcf->client.dev);
+ get_device(&pcf->client->dev);
pcf50633_work(&pcf->work);
return 0;
@@ -2631,74 +2547,29 @@ static int pcf50633_resume(struct device *dev)
#define pcf50633_resume NULL
#endif
+static struct i2c_device_id pcf50633_id_table[] = {
+ {"pcf50633", 0x73},
+};
+
static struct i2c_driver pcf50633_driver = {
.driver = {
.name = "pcf50633",
.suspend= pcf50633_suspend,
.resume = pcf50633_resume,
},
- .id = I2C_DRIVERID_PCF50633,
- .attach_adapter = pcf50633_attach_adapter,
- .detach_client = pcf50633_detach_client,
-};
-
-/* we have this purely to capture an early indication that we are coming out
- * of suspend, before our device resume got called; async interrupt service is
- * interested in this
- */
-
-static int pcf50633_plat_resume(struct platform_device *pdev)
-{
- /* i2c_get_clientdata(to_i2c_client(&pdev->dev)) returns NULL at this
- * early resume time so we have to use pcf50633_global
- */
- pcf50633_global->suspend_state = PCF50633_SS_RESUMING_BUT_NOT_US_YET;
-
- return 0;
-}
-
-/* platform driver, since i2c devices don't have platform_data */
-static int __init pcf50633_plat_probe(struct platform_device *pdev)
-{
- struct pcf50633_platform_data *pdata = pdev->dev.platform_data;
-
- if (!pdata)
- return -ENODEV;
-
- pcf50633_pdev = pdev;
-
- return 0;
-}
-
-static int pcf50633_plat_remove(struct platform_device *pdev)
-{
- return 0;
-}
-
-static struct platform_driver pcf50633_plat_driver = {
- .probe = pcf50633_plat_probe,
- .remove = pcf50633_plat_remove,
- .resume_early = pcf50633_plat_resume,
- .driver = {
- .owner = THIS_MODULE,
- .name = "pcf50633",
- },
+ .id_table = pcf50633_id_table,
+ .probe = pcf50633_probe,
+ .remove = pcf50633_remove,
};
static int __init pcf50633_init(void)
{
- int rc;
-
- if (!(rc = platform_driver_register(&pcf50633_plat_driver)))
- rc = i2c_add_driver(&pcf50633_driver);
-
- return rc;
+ return i2c_add_driver(&pcf50633_driver);
}
static void pcf50633_exit(void)
{
i2c_del_driver(&pcf50633_driver);
- platform_driver_unregister(&pcf50633_plat_driver);
}
MODULE_DESCRIPTION("I2C chip driver for NXP PCF50633 power management unit");
diff --git a/include/linux/pcf50633.h b/include/linux/pcf50633.h
index c11a637c2ac..1d44ebf10b7 100644
--- a/include/linux/pcf50633.h
+++ b/include/linux/pcf50633.h
@@ -76,10 +76,9 @@ enum pcf50633_reg_int5 {
};
struct pcf50633_data;
-extern struct pcf50633_data *pcf50633_global;
extern void
-pcf50633_go_standby(void);
+pcf50633_go_standby(struct pcf50633_data *pcf);
enum pcf50633_gpio {
PCF50633_GPIO1 = 1,
@@ -175,6 +174,9 @@ struct pcf50633_platform_data {
/* post-resume backlight bringup */
int defer_resume_backlight;
u8 resume_backlight_ramp_speed;
+
+ /* Runtime data */
+ struct pcf50633_data *pcf;
};
#endif /* _PCF50633_H */