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