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 --- |