Root/target/linux/s3c24xx/patches-2.6.30/056-pcf50633.patch

1--- a/drivers/mfd/pcf50633-core.c
2+++ b/drivers/mfd/pcf50633-core.c
3@@ -15,6 +15,7 @@
4 #include <linux/kernel.h>
5 #include <linux/device.h>
6 #include <linux/sysfs.h>
7+#include <linux/device.h>
8 #include <linux/module.h>
9 #include <linux/types.h>
10 #include <linux/interrupt.h>
11@@ -345,6 +346,8 @@ static void pcf50633_irq_worker(struct w
12         goto out;
13     }
14 
15+ pcf50633_reg_write(pcf, PCF50633_REG_OOCSHDWN, 0x04 ); /* defeat 8s death from lowsys on A5 */
16+
17     /* We immediately read the usb and adapter status. We thus make sure
18      * only of USBINS/USBREM IRQ handlers are called */
19     if (pcf_int[0] & (PCF50633_INT1_USBINS | PCF50633_INT1_USBREM)) {
20@@ -482,13 +485,13 @@ pcf50633_client_dev_register(struct pcf5
21 }
22 
23 #ifdef CONFIG_PM
24-static int pcf50633_suspend(struct device *dev, pm_message_t state)
25+static int pcf50633_suspend(struct i2c_client *client, pm_message_t state)
26 {
27     struct pcf50633 *pcf;
28     int ret = 0, i;
29     u8 res[5];
30 
31- pcf = dev_get_drvdata(dev);
32+ pcf = i2c_get_clientdata(client);
33 
34     /* Make sure our interrupt handlers are not called
35      * henceforth */
36@@ -523,12 +526,12 @@ out:
37     return ret;
38 }
39 
40-static int pcf50633_resume(struct device *dev)
41+static int pcf50633_resume(struct i2c_client *client)
42 {
43     struct pcf50633 *pcf;
44     int ret;
45 
46- pcf = dev_get_drvdata(dev);
47+ pcf = i2c_get_clientdata(client);
48 
49     /* Write the saved mask registers */
50     ret = pcf50633_write_block(pcf, PCF50633_REG_INT1M,
51@@ -625,6 +628,7 @@ static int __devinit pcf50633_probe(stru
52     }
53 
54     if (client->irq) {
55+ set_irq_handler(client->irq, handle_level_irq);
56         ret = request_irq(client->irq, pcf50633_irq,
57                 IRQF_TRIGGER_LOW, "pcf50633", pcf);
58 
59@@ -683,12 +687,12 @@ static struct i2c_device_id pcf50633_id_
60 static struct i2c_driver pcf50633_driver = {
61     .driver = {
62         .name = "pcf50633",
63- .suspend = pcf50633_suspend,
64- .resume = pcf50633_resume,
65     },
66     .id_table = pcf50633_id_table,
67     .probe = pcf50633_probe,
68     .remove = __devexit_p(pcf50633_remove),
69+ .suspend = pcf50633_suspend,
70+ .resume = pcf50633_resume,
71 };
72 
73 static int __init pcf50633_init(void)
74--- a/drivers/power/pcf50633-charger.c
75+++ b/drivers/power/pcf50633-charger.c
76@@ -36,6 +36,7 @@ struct pcf50633_mbc {
77 
78     struct power_supply usb;
79     struct power_supply adapter;
80+ struct power_supply ac;
81 
82     struct delayed_work charging_restart_work;
83 };
84@@ -47,16 +48,21 @@ int pcf50633_mbc_usb_curlim_set(struct p
85     u8 bits;
86     int charging_start = 1;
87     u8 mbcs2, chgmod;
88+ unsigned int mbcc5;
89 
90- if (ma >= 1000)
91+ if (ma >= 1000) {
92         bits = PCF50633_MBCC7_USB_1000mA;
93- else if (ma >= 500)
94+ ma = 1000;
95+ } else if (ma >= 500) {
96         bits = PCF50633_MBCC7_USB_500mA;
97- else if (ma >= 100)
98+ ma = 500;
99+ } else if (ma >= 100) {
100         bits = PCF50633_MBCC7_USB_100mA;
101- else {
102+ ma = 100;
103+ } else {
104         bits = PCF50633_MBCC7_USB_SUSPEND;
105         charging_start = 0;
106+ ma = 0;
107     }
108 
109     ret = pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_MBCC7,
110@@ -66,7 +72,22 @@ int pcf50633_mbc_usb_curlim_set(struct p
111     else
112         dev_info(pcf->dev, "usb curlim to %d mA\n", ma);
113 
114- /* Manual charging start */
115+ /*
116+ * We limit the charging current to be the USB current limit.
117+ * The reason is that on pcf50633, when it enters PMU Standby mode,
118+ * which it does when the device goes "off", the USB current limit
119+ * reverts to the variant default. In at least one common case, that
120+ * default is 500mA. By setting the charging current to be the same
121+ * as the USB limit we set here before PMU standby, we enforce it only
122+ * using the correct amount of current even when the USB current limit
123+ * gets reset to the wrong thing
124+ */
125+
126+ mbcc5 = (ma << 8) / mbc->pcf->pdata->chg_ref_current_ma;
127+ if (mbcc5 > 255)
128+ mbcc5 = 255;
129+ pcf50633_reg_write(mbc->pcf, PCF50633_REG_MBCC5, mbcc5);
130+
131     mbcs2 = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2);
132     chgmod = (mbcs2 & PCF50633_MBCS2_MBC_MASK);
133 
134@@ -81,7 +102,7 @@ int pcf50633_mbc_usb_curlim_set(struct p
135                 PCF50633_MBCC1_RESUME, PCF50633_MBCC1_RESUME);
136 
137     mbc->usb_active = charging_start;
138-
139+
140     power_supply_changed(&mbc->usb);
141 
142     return ret;
143@@ -156,9 +177,44 @@ static ssize_t set_usblim(struct device
144 
145 static DEVICE_ATTR(usb_curlim, S_IRUGO | S_IWUSR, show_usblim, set_usblim);
146 
147+static ssize_t
148+show_chglim(struct device *dev, struct device_attribute *attr, char *buf)
149+{
150+ struct pcf50633_mbc *mbc = dev_get_drvdata(dev);
151+ u8 mbcc5 = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCC5);
152+ unsigned int ma;
153+
154+ ma = (mbc->pcf->pdata->chg_ref_current_ma * mbcc5) >> 8;
155+
156+ return sprintf(buf, "%u\n", ma);
157+}
158+
159+static ssize_t set_chglim(struct device *dev,
160+ struct device_attribute *attr, const char *buf, size_t count)
161+{
162+ struct pcf50633_mbc *mbc = dev_get_drvdata(dev);
163+ unsigned long ma;
164+ unsigned int mbcc5;
165+ int ret;
166+
167+ ret = strict_strtoul(buf, 10, &ma);
168+ if (ret)
169+ return -EINVAL;
170+
171+ mbcc5 = (ma << 8) / mbc->pcf->pdata->chg_ref_current_ma;
172+ if (mbcc5 > 255)
173+ mbcc5 = 255;
174+ pcf50633_reg_write(mbc->pcf, PCF50633_REG_MBCC5, mbcc5);
175+
176+ return count;
177+}
178+
179+static DEVICE_ATTR(chg_curlim, S_IRUGO | S_IWUSR, show_chglim, set_chglim);
180+
181 static struct attribute *pcf50633_mbc_sysfs_entries[] = {
182     &dev_attr_chgmode.attr,
183     &dev_attr_usb_curlim.attr,
184+ &dev_attr_chg_curlim.attr,
185     NULL,
186 };
187 
188@@ -239,6 +295,7 @@ pcf50633_mbc_irq_handler(int irq, void *
189 
190     power_supply_changed(&mbc->usb);
191     power_supply_changed(&mbc->adapter);
192+ power_supply_changed(&mbc->ac);
193 
194     if (mbc->pcf->pdata->mbc_event_callback)
195         mbc->pcf->pdata->mbc_event_callback(mbc->pcf, irq);
196@@ -248,8 +305,7 @@ static int adapter_get_property(struct p
197             enum power_supply_property psp,
198             union power_supply_propval *val)
199 {
200- struct pcf50633_mbc *mbc = container_of(psy,
201- struct pcf50633_mbc, adapter);
202+ struct pcf50633_mbc *mbc = container_of(psy, struct pcf50633_mbc, adapter);
203     int ret = 0;
204 
205     switch (psp) {
206@@ -269,10 +325,34 @@ static int usb_get_property(struct power
207 {
208     struct pcf50633_mbc *mbc = container_of(psy, struct pcf50633_mbc, usb);
209     int ret = 0;
210+ u8 usblim = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCC7) &
211+ PCF50633_MBCC7_USB_MASK;
212 
213     switch (psp) {
214     case POWER_SUPPLY_PROP_ONLINE:
215- val->intval = mbc->usb_online;
216+ val->intval = mbc->usb_online &&
217+ (usblim <= PCF50633_MBCC7_USB_500mA);
218+ break;
219+ default:
220+ ret = -EINVAL;
221+ break;
222+ }
223+ return ret;
224+}
225+
226+static int ac_get_property(struct power_supply *psy,
227+ enum power_supply_property psp,
228+ union power_supply_propval *val)
229+{
230+ struct pcf50633_mbc *mbc = container_of(psy, struct pcf50633_mbc, ac);
231+ int ret = 0;
232+ u8 usblim = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCC7) &
233+ PCF50633_MBCC7_USB_MASK;
234+
235+ switch (psp) {
236+ case POWER_SUPPLY_PROP_ONLINE:
237+ val->intval = mbc->usb_online &&
238+ (usblim == PCF50633_MBCC7_USB_1000mA);
239         break;
240     default:
241         ret = -EINVAL;
242@@ -337,6 +417,17 @@ static int __devinit pcf50633_mbc_probe(
243     mbc->usb.supplied_to = mbc->pcf->pdata->batteries;
244     mbc->usb.num_supplicants = mbc->pcf->pdata->num_batteries;
245 
246+ mbc->ac.name = "ac";
247+ mbc->ac.type = POWER_SUPPLY_TYPE_MAINS;
248+ mbc->ac.properties = power_props;
249+ mbc->ac.num_properties = ARRAY_SIZE(power_props);
250+ mbc->ac.get_property = ac_get_property;
251+ mbc->ac.supplied_to = mbc->pcf->pdata->batteries;
252+ mbc->ac.num_supplicants = mbc->pcf->pdata->num_batteries;
253+
254+ INIT_DELAYED_WORK(&mbc->charging_restart_work,
255+ pcf50633_mbc_charging_restart);
256+
257     ret = power_supply_register(&pdev->dev, &mbc->adapter);
258     if (ret) {
259         dev_err(mbc->pcf->dev, "failed to register adapter\n");
260@@ -352,9 +443,15 @@ static int __devinit pcf50633_mbc_probe(
261         return ret;
262     }
263 
264- INIT_DELAYED_WORK(&mbc->charging_restart_work,
265- pcf50633_mbc_charging_restart);
266-
267+ ret = power_supply_register(&pdev->dev, &mbc->ac);
268+ if (ret) {
269+ dev_err(mbc->pcf->dev, "failed to register ac\n");
270+ power_supply_unregister(&mbc->adapter);
271+ power_supply_unregister(&mbc->usb);
272+ kfree(mbc);
273+ return ret;
274+ }
275+
276     ret = sysfs_create_group(&pdev->dev.kobj, &mbc_attr_group);
277     if (ret)
278         dev_err(mbc->pcf->dev, "failed to create sysfs entries\n");
279--- a/drivers/rtc/rtc-pcf50633.c
280+++ b/drivers/rtc/rtc-pcf50633.c
281@@ -58,6 +58,7 @@ struct pcf50633_time {
282 struct pcf50633_rtc {
283     int alarm_enabled;
284     int second_enabled;
285+ int alarm_pending;
286 
287     struct pcf50633 *pcf;
288     struct rtc_device *rtc_dev;
289@@ -70,7 +71,7 @@ static void pcf2rtc_time(struct rtc_time
290     rtc->tm_hour = bcd2bin(pcf->time[PCF50633_TI_HOUR]);
291     rtc->tm_wday = bcd2bin(pcf->time[PCF50633_TI_WKDAY]);
292     rtc->tm_mday = bcd2bin(pcf->time[PCF50633_TI_DAY]);
293- rtc->tm_mon = bcd2bin(pcf->time[PCF50633_TI_MONTH]);
294+ rtc->tm_mon = bcd2bin(pcf->time[PCF50633_TI_MONTH]) - 1;
295     rtc->tm_year = bcd2bin(pcf->time[PCF50633_TI_YEAR]) + 100;
296 }
297 
298@@ -81,7 +82,7 @@ static void rtc2pcf_time(struct pcf50633
299     pcf->time[PCF50633_TI_HOUR] = bin2bcd(rtc->tm_hour);
300     pcf->time[PCF50633_TI_WKDAY] = bin2bcd(rtc->tm_wday);
301     pcf->time[PCF50633_TI_DAY] = bin2bcd(rtc->tm_mday);
302- pcf->time[PCF50633_TI_MONTH] = bin2bcd(rtc->tm_mon);
303+ pcf->time[PCF50633_TI_MONTH] = bin2bcd(rtc->tm_mon + 1);
304     pcf->time[PCF50633_TI_YEAR] = bin2bcd(rtc->tm_year % 100);
305 }
306 
307@@ -209,6 +210,7 @@ static int pcf50633_rtc_read_alarm(struc
308     rtc = dev_get_drvdata(dev);
309 
310     alrm->enabled = rtc->alarm_enabled;
311+ alrm->pending = rtc->alarm_pending;
312 
313     ret = pcf50633_read_block(rtc->pcf, PCF50633_REG_RTCSCA,
314                 PCF50633_TI_EXTENT, &pcf_tm.time[0]);
315@@ -244,9 +246,12 @@ static int pcf50633_rtc_set_alarm(struct
316     /* Returns 0 on success */
317     ret = pcf50633_write_block(rtc->pcf, PCF50633_REG_RTCSCA,
318                 PCF50633_TI_EXTENT, &pcf_tm.time[0]);
319+ if (!alrm->enabled)
320+ rtc->alarm_pending = 0;
321 
322- if (!alarm_masked)
323+ if (!alarm_masked || alrm->enabled)
324         pcf50633_irq_unmask(rtc->pcf, PCF50633_IRQ_ALARM);
325+ rtc->alarm_enabled = alrm->enabled;
326 
327     return ret;
328 }
329@@ -267,6 +272,7 @@ static void pcf50633_rtc_irq(int irq, vo
330     switch (irq) {
331     case PCF50633_IRQ_ALARM:
332         rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF);
333+ rtc->alarm_pending = 1;
334         break;
335     case PCF50633_IRQ_SECOND:
336         rtc_update_irq(rtc->rtc_dev, 1, RTC_UF | RTC_IRQF);
337--- a/include/linux/mfd/pcf50633/core.h
338+++ b/include/linux/mfd/pcf50633/core.h
339@@ -31,6 +31,8 @@ struct pcf50633_platform_data {
340 
341     int charging_restart_interval;
342 
343+ int chg_ref_current_ma;
344+
345     /* Callbacks */
346     void (*probe_done)(struct pcf50633 *);
347     void (*mbc_event_callback)(struct pcf50633 *, int);
348@@ -208,7 +210,8 @@ enum pcf50633_reg_int5 {
349 };
350 
351 /* misc. registers */
352-#define PCF50633_REG_OOCSHDWN 0x0c
353+#define PCF50633_REG_OOCSHDWN 0x0c
354+#define PCF50633_OOCSHDWN_GOSTDBY 0x01
355 
356 /* LED registers */
357 #define PCF50633_REG_LEDOUT 0x28
358--- a/drivers/regulator/pcf50633-regulator.c
359+++ b/drivers/regulator/pcf50633-regulator.c
360@@ -24,11 +24,12 @@
361 #include <linux/mfd/pcf50633/core.h>
362 #include <linux/mfd/pcf50633/pmic.h>
363 
364-#define PCF50633_REGULATOR(_name, _id) \
365+#define PCF50633_REGULATOR(_name, _id, _n) \
366     { \
367         .name = _name, \
368         .id = _id, \
369         .ops = &pcf50633_regulator_ops, \
370+ .n_voltages = _n, \
371         .type = REGULATOR_VOLTAGE, \
372         .owner = THIS_MODULE, \
373     }
374@@ -193,6 +194,40 @@ static int pcf50633_regulator_get_voltag
375     return millivolts * 1000;
376 }
377 
378+static int pcf50633_regulator_list_voltage(struct regulator_dev *rdev,
379+ unsigned int index)
380+{
381+ struct pcf50633 *pcf;
382+ int regulator_id, millivolts;
383+
384+ pcf = rdev_get_drvdata(rdev);;
385+
386+ regulator_id = rdev_get_id(rdev);
387+
388+ switch (regulator_id) {
389+ case PCF50633_REGULATOR_AUTO:
390+ millivolts = auto_voltage_value(index + 0x2f);
391+ break;
392+ case PCF50633_REGULATOR_DOWN1:
393+ case PCF50633_REGULATOR_DOWN2:
394+ millivolts = down_voltage_value(index);
395+ break;
396+ case PCF50633_REGULATOR_LDO1:
397+ case PCF50633_REGULATOR_LDO2:
398+ case PCF50633_REGULATOR_LDO3:
399+ case PCF50633_REGULATOR_LDO4:
400+ case PCF50633_REGULATOR_LDO5:
401+ case PCF50633_REGULATOR_LDO6:
402+ case PCF50633_REGULATOR_HCLDO:
403+ millivolts = ldo_voltage_value(index);
404+ break;
405+ default:
406+ return -EINVAL;
407+ }
408+
409+ return millivolts * 1000;
410+}
411+
412 static int pcf50633_regulator_enable(struct regulator_dev *rdev)
413 {
414     struct pcf50633 *pcf = rdev_get_drvdata(rdev);
415@@ -246,6 +281,7 @@ static int pcf50633_regulator_is_enabled
416 static struct regulator_ops pcf50633_regulator_ops = {
417     .set_voltage = pcf50633_regulator_set_voltage,
418     .get_voltage = pcf50633_regulator_get_voltage,
419+ .list_voltage = pcf50633_regulator_list_voltage,
420     .enable = pcf50633_regulator_enable,
421     .disable = pcf50633_regulator_disable,
422     .is_enabled = pcf50633_regulator_is_enabled,
423@@ -253,27 +289,27 @@ static struct regulator_ops pcf50633_reg
424 
425 static struct regulator_desc regulators[] = {
426     [PCF50633_REGULATOR_AUTO] =
427- PCF50633_REGULATOR("auto", PCF50633_REGULATOR_AUTO),
428+ PCF50633_REGULATOR("auto", PCF50633_REGULATOR_AUTO, 80),
429     [PCF50633_REGULATOR_DOWN1] =
430- PCF50633_REGULATOR("down1", PCF50633_REGULATOR_DOWN1),
431+ PCF50633_REGULATOR("down1", PCF50633_REGULATOR_DOWN1, 95),
432     [PCF50633_REGULATOR_DOWN2] =
433- PCF50633_REGULATOR("down2", PCF50633_REGULATOR_DOWN2),
434+ PCF50633_REGULATOR("down2", PCF50633_REGULATOR_DOWN2, 95),
435     [PCF50633_REGULATOR_LDO1] =
436- PCF50633_REGULATOR("ldo1", PCF50633_REGULATOR_LDO1),
437+ PCF50633_REGULATOR("ldo1", PCF50633_REGULATOR_LDO1, 27),
438     [PCF50633_REGULATOR_LDO2] =
439- PCF50633_REGULATOR("ldo2", PCF50633_REGULATOR_LDO2),
440+ PCF50633_REGULATOR("ldo2", PCF50633_REGULATOR_LDO2, 27),
441     [PCF50633_REGULATOR_LDO3] =
442- PCF50633_REGULATOR("ldo3", PCF50633_REGULATOR_LDO3),
443+ PCF50633_REGULATOR("ldo3", PCF50633_REGULATOR_LDO3, 27),
444     [PCF50633_REGULATOR_LDO4] =
445- PCF50633_REGULATOR("ldo4", PCF50633_REGULATOR_LDO4),
446+ PCF50633_REGULATOR("ldo4", PCF50633_REGULATOR_LDO4, 27),
447     [PCF50633_REGULATOR_LDO5] =
448- PCF50633_REGULATOR("ldo5", PCF50633_REGULATOR_LDO5),
449+ PCF50633_REGULATOR("ldo5", PCF50633_REGULATOR_LDO5, 27),
450     [PCF50633_REGULATOR_LDO6] =
451- PCF50633_REGULATOR("ldo6", PCF50633_REGULATOR_LDO6),
452+ PCF50633_REGULATOR("ldo6", PCF50633_REGULATOR_LDO6, 27),
453     [PCF50633_REGULATOR_HCLDO] =
454- PCF50633_REGULATOR("hcldo", PCF50633_REGULATOR_HCLDO),
455+ PCF50633_REGULATOR("hcldo", PCF50633_REGULATOR_HCLDO, 26),
456     [PCF50633_REGULATOR_MEMLDO] =
457- PCF50633_REGULATOR("memldo", PCF50633_REGULATOR_MEMLDO),
458+ PCF50633_REGULATOR("memldo", PCF50633_REGULATOR_MEMLDO, 27),
459 };
460 
461 static int __devinit pcf50633_regulator_probe(struct platform_device *pdev)
462

Archive Download this file



interactive