| Mark Brown | 1910efa | 2012-06-23 13:07:57 +0100 | [diff] [blame] | 1 | /* | 
|  | 2 | * arizona-ldo1.c  --  LDO1 supply for Arizona devices | 
|  | 3 | * | 
|  | 4 | * Copyright 2012 Wolfson Microelectronics PLC. | 
|  | 5 | * | 
|  | 6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | 
|  | 7 | * | 
|  | 8 | *  This program is free software; you can redistribute  it and/or modify it | 
|  | 9 | *  under  the terms of  the GNU General  Public License as published by the | 
|  | 10 | *  Free Software Foundation;  either version 2 of the  License, or (at your | 
|  | 11 | *  option) any later version. | 
|  | 12 | */ | 
|  | 13 |  | 
|  | 14 | #include <linux/module.h> | 
|  | 15 | #include <linux/moduleparam.h> | 
|  | 16 | #include <linux/init.h> | 
|  | 17 | #include <linux/bitops.h> | 
|  | 18 | #include <linux/err.h> | 
|  | 19 | #include <linux/platform_device.h> | 
|  | 20 | #include <linux/regulator/driver.h> | 
|  | 21 | #include <linux/regulator/machine.h> | 
|  | 22 | #include <linux/gpio.h> | 
|  | 23 | #include <linux/slab.h> | 
|  | 24 |  | 
|  | 25 | #include <linux/mfd/arizona/core.h> | 
|  | 26 | #include <linux/mfd/arizona/pdata.h> | 
|  | 27 | #include <linux/mfd/arizona/registers.h> | 
|  | 28 |  | 
|  | 29 | struct arizona_ldo1 { | 
|  | 30 | struct regulator_dev *regulator; | 
|  | 31 | struct arizona *arizona; | 
|  | 32 |  | 
|  | 33 | struct regulator_consumer_supply supply; | 
|  | 34 | struct regulator_init_data init_data; | 
|  | 35 | }; | 
|  | 36 |  | 
|  | 37 | static struct regulator_ops arizona_ldo1_ops = { | 
|  | 38 | .list_voltage = regulator_list_voltage_linear, | 
|  | 39 | .map_voltage = regulator_map_voltage_linear, | 
|  | 40 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | 
|  | 41 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | 
|  | 42 | }; | 
|  | 43 |  | 
|  | 44 | static const struct regulator_desc arizona_ldo1 = { | 
|  | 45 | .name = "LDO1", | 
|  | 46 | .supply_name = "LDOVDD", | 
|  | 47 | .type = REGULATOR_VOLTAGE, | 
|  | 48 | .ops = &arizona_ldo1_ops, | 
|  | 49 |  | 
|  | 50 | .vsel_reg = ARIZONA_LDO1_CONTROL_1, | 
|  | 51 | .vsel_mask = ARIZONA_LDO1_VSEL_MASK, | 
|  | 52 | .min_uV = 900000, | 
|  | 53 | .uV_step = 50000, | 
|  | 54 | .n_voltages = 7, | 
|  | 55 |  | 
|  | 56 | .owner = THIS_MODULE, | 
|  | 57 | }; | 
|  | 58 |  | 
|  | 59 | static const struct regulator_init_data arizona_ldo1_default = { | 
| Mark Brown | a9905b1 | 2012-06-27 14:32:06 +0100 | [diff] [blame] | 60 | .constraints = { | 
|  | 61 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | 
|  | 62 | }, | 
| Mark Brown | 1910efa | 2012-06-23 13:07:57 +0100 | [diff] [blame] | 63 | .num_consumer_supplies = 1, | 
|  | 64 | }; | 
|  | 65 |  | 
|  | 66 | static __devinit int arizona_ldo1_probe(struct platform_device *pdev) | 
|  | 67 | { | 
|  | 68 | struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); | 
|  | 69 | struct regulator_config config = { }; | 
|  | 70 | struct arizona_ldo1 *ldo1; | 
|  | 71 | int ret; | 
|  | 72 |  | 
|  | 73 | ldo1 = devm_kzalloc(&pdev->dev, sizeof(*ldo1), GFP_KERNEL); | 
|  | 74 | if (ldo1 == NULL) { | 
|  | 75 | dev_err(&pdev->dev, "Unable to allocate private data\n"); | 
|  | 76 | return -ENOMEM; | 
|  | 77 | } | 
|  | 78 |  | 
|  | 79 | ldo1->arizona = arizona; | 
|  | 80 |  | 
|  | 81 | /* | 
|  | 82 | * Since the chip usually supplies itself we provide some | 
|  | 83 | * default init_data for it.  This will be overridden with | 
|  | 84 | * platform data if provided. | 
|  | 85 | */ | 
|  | 86 | ldo1->init_data = arizona_ldo1_default; | 
|  | 87 | ldo1->init_data.consumer_supplies = &ldo1->supply; | 
|  | 88 | ldo1->supply.supply = "DCVDD"; | 
|  | 89 | ldo1->supply.dev_name = dev_name(arizona->dev); | 
|  | 90 |  | 
|  | 91 | config.dev = arizona->dev; | 
|  | 92 | config.driver_data = ldo1; | 
|  | 93 | config.regmap = arizona->regmap; | 
| Mark Brown | a9905b1 | 2012-06-27 14:32:06 +0100 | [diff] [blame] | 94 | config.ena_gpio = arizona->pdata.ldoena; | 
| Mark Brown | 1910efa | 2012-06-23 13:07:57 +0100 | [diff] [blame] | 95 |  | 
|  | 96 | if (arizona->pdata.ldo1) | 
|  | 97 | config.init_data = arizona->pdata.ldo1; | 
|  | 98 | else | 
|  | 99 | config.init_data = &ldo1->init_data; | 
|  | 100 |  | 
|  | 101 | ldo1->regulator = regulator_register(&arizona_ldo1, &config); | 
|  | 102 | if (IS_ERR(ldo1->regulator)) { | 
|  | 103 | ret = PTR_ERR(ldo1->regulator); | 
|  | 104 | dev_err(arizona->dev, "Failed to register LDO1 supply: %d\n", | 
|  | 105 | ret); | 
|  | 106 | return ret; | 
|  | 107 | } | 
|  | 108 |  | 
|  | 109 | platform_set_drvdata(pdev, ldo1); | 
|  | 110 |  | 
|  | 111 | return 0; | 
|  | 112 | } | 
|  | 113 |  | 
|  | 114 | static __devexit int arizona_ldo1_remove(struct platform_device *pdev) | 
|  | 115 | { | 
|  | 116 | struct arizona_ldo1 *ldo1 = platform_get_drvdata(pdev); | 
|  | 117 |  | 
|  | 118 | regulator_unregister(ldo1->regulator); | 
|  | 119 |  | 
|  | 120 | return 0; | 
|  | 121 | } | 
|  | 122 |  | 
|  | 123 | static struct platform_driver arizona_ldo1_driver = { | 
|  | 124 | .probe = arizona_ldo1_probe, | 
|  | 125 | .remove = __devexit_p(arizona_ldo1_remove), | 
|  | 126 | .driver		= { | 
|  | 127 | .name	= "arizona-ldo1", | 
|  | 128 | .owner	= THIS_MODULE, | 
|  | 129 | }, | 
|  | 130 | }; | 
|  | 131 |  | 
|  | 132 | module_platform_driver(arizona_ldo1_driver); | 
|  | 133 |  | 
|  | 134 | /* Module information */ | 
|  | 135 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | 
|  | 136 | MODULE_DESCRIPTION("Arizona LDO1 driver"); | 
|  | 137 | MODULE_LICENSE("GPL"); | 
|  | 138 | MODULE_ALIAS("platform:arizona-ldo1"); |