88pm8607.c (35858adbfca13678af99fb31618ef4428d6dedb0) 88pm8607.c (53dbab7af9ca13fa95605e9a5c31bb803dcba363)
1/*
2 * Regulators driver for Marvell 88PM8607
3 *
4 * Copyright (C) 2009 Marvell International Ltd.
5 * Haojian Zhuang <haojian.zhuang@marvell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/kernel.h>
12#include <linux/init.h>
13#include <linux/err.h>
1/*
2 * Regulators driver for Marvell 88PM8607
3 *
4 * Copyright (C) 2009 Marvell International Ltd.
5 * Haojian Zhuang <haojian.zhuang@marvell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/kernel.h>
12#include <linux/init.h>
13#include <linux/err.h>
14#include <linux/i2c.h>
14#include <linux/platform_device.h>
15#include <linux/regulator/driver.h>
16#include <linux/regulator/machine.h>
15#include <linux/platform_device.h>
16#include <linux/regulator/driver.h>
17#include <linux/regulator/machine.h>
17#include <linux/mfd/88pm8607.h>
18#include <linux/mfd/88pm860x.h>
18
19struct pm8607_regulator_info {
20 struct regulator_desc desc;
19
20struct pm8607_regulator_info {
21 struct regulator_desc desc;
21 struct pm8607_chip *chip;
22 struct pm860x_chip *chip;
22 struct regulator_dev *regulator;
23 struct regulator_dev *regulator;
24 struct i2c_client *i2c;
23
24 int min_uV;
25 int max_uV;
26 int step_uV;
27 int vol_reg;
28 int vol_shift;
29 int vol_nbits;
30 int update_reg;

--- 10 unchanged lines hidden (view full) ---

41 return -EINVAL;
42
43 return 0;
44}
45
46static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index)
47{
48 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
25
26 int min_uV;
27 int max_uV;
28 int step_uV;
29 int vol_reg;
30 int vol_shift;
31 int vol_nbits;
32 int update_reg;

--- 10 unchanged lines hidden (view full) ---

43 return -EINVAL;
44
45 return 0;
46}
47
48static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index)
49{
50 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
49 uint8_t chip_id = info->chip->chip_id;
51 uint8_t chip_id = info->chip->chip_version;
50 int ret = -EINVAL;
51
52 switch (info->desc.id) {
53 case PM8607_ID_BUCK1:
54 ret = (index < 0x1d) ? (index * 25000 + 800000) :
55 ((index < 0x20) ? 1500000 :
56 ((index < 0x40) ? ((index - 0x20) * 25000) :
57 -EINVAL));

--- 106 unchanged lines hidden (view full) ---

164 break;
165 }
166 return ret;
167}
168
169static int choose_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
170{
171 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
52 int ret = -EINVAL;
53
54 switch (info->desc.id) {
55 case PM8607_ID_BUCK1:
56 ret = (index < 0x1d) ? (index * 25000 + 800000) :
57 ((index < 0x20) ? 1500000 :
58 ((index < 0x40) ? ((index - 0x20) * 25000) :
59 -EINVAL));

--- 106 unchanged lines hidden (view full) ---

166 break;
167 }
168 return ret;
169}
170
171static int choose_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
172{
173 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
172 uint8_t chip_id = info->chip->chip_id;
174 uint8_t chip_id = info->chip->chip_version;
173 int val = -ENOENT;
174 int ret;
175
176 switch (info->desc.id) {
177 case PM8607_ID_BUCK1:
178 if (min_uV >= 800000) /* 800mV ~ 1500mV / 25mV */
179 val = (min_uV - 775001) / 25000;
180 else { /* 25mV ~ 775mV / 25mV */

--- 242 unchanged lines hidden (view full) ---

423 pr_err("invalid voltage range (%d %d) uV", min_uV, max_uV);
424 return val;
425}
426
427static int pm8607_set_voltage(struct regulator_dev *rdev,
428 int min_uV, int max_uV)
429{
430 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
175 int val = -ENOENT;
176 int ret;
177
178 switch (info->desc.id) {
179 case PM8607_ID_BUCK1:
180 if (min_uV >= 800000) /* 800mV ~ 1500mV / 25mV */
181 val = (min_uV - 775001) / 25000;
182 else { /* 25mV ~ 775mV / 25mV */

--- 242 unchanged lines hidden (view full) ---

425 pr_err("invalid voltage range (%d %d) uV", min_uV, max_uV);
426 return val;
427}
428
429static int pm8607_set_voltage(struct regulator_dev *rdev,
430 int min_uV, int max_uV)
431{
432 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
431 struct pm8607_chip *chip = info->chip;
432 uint8_t val, mask;
433 int ret;
434
435 if (check_range(info, min_uV, max_uV)) {
436 pr_err("invalid voltage range (%d, %d) uV\n", min_uV, max_uV);
437 return -EINVAL;
438 }
439
440 ret = choose_voltage(rdev, min_uV, max_uV);
441 if (ret < 0)
442 return -EINVAL;
443 val = (uint8_t)(ret << info->vol_shift);
444 mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
445
433 uint8_t val, mask;
434 int ret;
435
436 if (check_range(info, min_uV, max_uV)) {
437 pr_err("invalid voltage range (%d, %d) uV\n", min_uV, max_uV);
438 return -EINVAL;
439 }
440
441 ret = choose_voltage(rdev, min_uV, max_uV);
442 if (ret < 0)
443 return -EINVAL;
444 val = (uint8_t)(ret << info->vol_shift);
445 mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
446
446 ret = pm8607_set_bits(chip, info->vol_reg, mask, val);
447 ret = pm860x_set_bits(info->i2c, info->vol_reg, mask, val);
447 if (ret)
448 return ret;
449 switch (info->desc.id) {
450 case PM8607_ID_BUCK1:
451 case PM8607_ID_BUCK3:
448 if (ret)
449 return ret;
450 switch (info->desc.id) {
451 case PM8607_ID_BUCK1:
452 case PM8607_ID_BUCK3:
452 ret = pm8607_set_bits(chip, info->update_reg,
453 ret = pm860x_set_bits(info->i2c, info->update_reg,
453 1 << info->update_bit,
454 1 << info->update_bit);
455 break;
456 }
457 return ret;
458}
459
460static int pm8607_get_voltage(struct regulator_dev *rdev)
461{
462 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
454 1 << info->update_bit,
455 1 << info->update_bit);
456 break;
457 }
458 return ret;
459}
460
461static int pm8607_get_voltage(struct regulator_dev *rdev)
462{
463 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
463 struct pm8607_chip *chip = info->chip;
464 uint8_t val, mask;
465 int ret;
466
464 uint8_t val, mask;
465 int ret;
466
467 ret = pm8607_reg_read(chip, info->vol_reg);
467 ret = pm860x_reg_read(info->i2c, info->vol_reg);
468 if (ret < 0)
469 return ret;
470
471 mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
472 val = ((unsigned char)ret & mask) >> info->vol_shift;
473
474 return pm8607_list_voltage(rdev, val);
475}
476
477static int pm8607_enable(struct regulator_dev *rdev)
478{
479 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
468 if (ret < 0)
469 return ret;
470
471 mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
472 val = ((unsigned char)ret & mask) >> info->vol_shift;
473
474 return pm8607_list_voltage(rdev, val);
475}
476
477static int pm8607_enable(struct regulator_dev *rdev)
478{
479 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
480 struct pm8607_chip *chip = info->chip;
481
480
482 return pm8607_set_bits(chip, info->enable_reg,
481 return pm860x_set_bits(info->i2c, info->enable_reg,
483 1 << info->enable_bit,
484 1 << info->enable_bit);
485}
486
487static int pm8607_disable(struct regulator_dev *rdev)
488{
489 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
482 1 << info->enable_bit,
483 1 << info->enable_bit);
484}
485
486static int pm8607_disable(struct regulator_dev *rdev)
487{
488 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
490 struct pm8607_chip *chip = info->chip;
491
489
492 return pm8607_set_bits(chip, info->enable_reg,
490 return pm860x_set_bits(info->i2c, info->enable_reg,
493 1 << info->enable_bit, 0);
494}
495
496static int pm8607_is_enabled(struct regulator_dev *rdev)
497{
498 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
491 1 << info->enable_bit, 0);
492}
493
494static int pm8607_is_enabled(struct regulator_dev *rdev)
495{
496 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
499 struct pm8607_chip *chip = info->chip;
500 int ret;
501
497 int ret;
498
502 ret = pm8607_reg_read(chip, info->enable_reg);
499 ret = pm860x_reg_read(info->i2c, info->enable_reg);
503 if (ret < 0)
504 return ret;
505
506 return !!((unsigned char)ret & (1 << info->enable_bit));
507}
508
509static struct regulator_ops pm8607_regulator_ops = {
510 .set_voltage = pm8607_set_voltage,

--- 73 unchanged lines hidden (view full) ---

584 if (info->desc.id == id)
585 return info;
586 }
587 return NULL;
588}
589
590static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
591{
500 if (ret < 0)
501 return ret;
502
503 return !!((unsigned char)ret & (1 << info->enable_bit));
504}
505
506static struct regulator_ops pm8607_regulator_ops = {
507 .set_voltage = pm8607_set_voltage,

--- 73 unchanged lines hidden (view full) ---

581 if (info->desc.id == id)
582 return info;
583 }
584 return NULL;
585}
586
587static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
588{
592 struct pm8607_chip *chip = dev_get_drvdata(pdev->dev.parent);
593 struct pm8607_platform_data *pdata = chip->dev->platform_data;
589 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
590 struct pm860x_platform_data *pdata = chip->dev->platform_data;
594 struct pm8607_regulator_info *info = NULL;
595
596 info = find_regulator_info(pdev->id);
597 if (info == NULL) {
598 dev_err(&pdev->dev, "invalid regulator ID specified\n");
599 return -EINVAL;
600 }
601
591 struct pm8607_regulator_info *info = NULL;
592
593 info = find_regulator_info(pdev->id);
594 if (info == NULL) {
595 dev_err(&pdev->dev, "invalid regulator ID specified\n");
596 return -EINVAL;
597 }
598
599 info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
602 info->chip = chip;
603
604 info->regulator = regulator_register(&info->desc, &pdev->dev,
605 pdata->regulator[pdev->id], info);
606 if (IS_ERR(info->regulator)) {
607 dev_err(&pdev->dev, "failed to register regulator %s\n",
608 info->desc.name);
609 return PTR_ERR(info->regulator);

--- 76 unchanged lines hidden ---
600 info->chip = chip;
601
602 info->regulator = regulator_register(&info->desc, &pdev->dev,
603 pdata->regulator[pdev->id], info);
604 if (IS_ERR(info->regulator)) {
605 dev_err(&pdev->dev, "failed to register regulator %s\n",
606 info->desc.name);
607 return PTR_ERR(info->regulator);

--- 76 unchanged lines hidden ---