1f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park/* 2f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park * linux/drivers/regulator/aat2870-regulator.c 3f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park * 4f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park * Copyright (c) 2011, NVIDIA Corporation. 5f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park * Author: Jin Park <jinyoungp@nvidia.com> 6f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park * 7f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park * This program is free software; you can redistribute it and/or 8f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park * modify it under the terms of the GNU General Public License 9f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park * version 2 as published by the Free Software Foundation. 10f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park * 11f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park * This program is distributed in the hope that it will be useful, but 12f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park * WITHOUT ANY WARRANTY; without even the implied warranty of 13f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park * General Public License for more details. 15f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park * 16f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park * You should have received a copy of the GNU General Public License 17f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park * along with this program; if not, write to the Free Software 18f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 19f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park * 02110-1301 USA 20f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park */ 21f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 22f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park#include <linux/kernel.h> 23f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park#include <linux/init.h> 24f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park#include <linux/err.h> 253a7d021b5e1de205c964c30d0ceda660501dc107Randy Dunlap#include <linux/module.h> 26f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park#include <linux/slab.h> 27f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park#include <linux/platform_device.h> 28f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park#include <linux/regulator/driver.h> 29f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park#include <linux/regulator/machine.h> 30f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park#include <linux/mfd/aat2870.h> 31f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 32f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstruct aat2870_regulator { 33b21bcd1ada026cd90243311e89dd8d999fe0a227Axel Lin struct aat2870_data *aat2870; 34f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park struct regulator_desc desc; 35f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 36f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park u8 enable_addr; 37f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park u8 enable_shift; 38f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park u8 enable_mask; 39f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 40f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park u8 voltage_addr; 41f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park u8 voltage_shift; 42f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park u8 voltage_mask; 43f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park}; 44f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 45f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic int aat2870_ldo_set_voltage_sel(struct regulator_dev *rdev, 46f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park unsigned selector) 47f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park{ 48f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park struct aat2870_regulator *ri = rdev_get_drvdata(rdev); 49b21bcd1ada026cd90243311e89dd8d999fe0a227Axel Lin struct aat2870_data *aat2870 = ri->aat2870; 50f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 51f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park return aat2870->update(aat2870, ri->voltage_addr, ri->voltage_mask, 52a5228d2e5ea02c90581d5957cb6c4c73c191298fAxel Lin selector << ri->voltage_shift); 53f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park} 54f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 55f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic int aat2870_ldo_get_voltage_sel(struct regulator_dev *rdev) 56f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park{ 57f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park struct aat2870_regulator *ri = rdev_get_drvdata(rdev); 58b21bcd1ada026cd90243311e89dd8d999fe0a227Axel Lin struct aat2870_data *aat2870 = ri->aat2870; 59f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park u8 val; 60f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park int ret; 61f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 62f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park ret = aat2870->read(aat2870, ri->voltage_addr, &val); 63f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park if (ret) 64f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park return ret; 65f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 66f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park return (val & ri->voltage_mask) >> ri->voltage_shift; 67f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park} 68f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 69f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic int aat2870_ldo_enable(struct regulator_dev *rdev) 70f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park{ 71f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park struct aat2870_regulator *ri = rdev_get_drvdata(rdev); 72b21bcd1ada026cd90243311e89dd8d999fe0a227Axel Lin struct aat2870_data *aat2870 = ri->aat2870; 73f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 74f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park return aat2870->update(aat2870, ri->enable_addr, ri->enable_mask, 75f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park ri->enable_mask); 76f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park} 77f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 78f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic int aat2870_ldo_disable(struct regulator_dev *rdev) 79f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park{ 80f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park struct aat2870_regulator *ri = rdev_get_drvdata(rdev); 81b21bcd1ada026cd90243311e89dd8d999fe0a227Axel Lin struct aat2870_data *aat2870 = ri->aat2870; 82f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 83f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park return aat2870->update(aat2870, ri->enable_addr, ri->enable_mask, 0); 84f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park} 85f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 86f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic int aat2870_ldo_is_enabled(struct regulator_dev *rdev) 87f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park{ 88f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park struct aat2870_regulator *ri = rdev_get_drvdata(rdev); 89b21bcd1ada026cd90243311e89dd8d999fe0a227Axel Lin struct aat2870_data *aat2870 = ri->aat2870; 90f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park u8 val; 91f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park int ret; 92f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 93f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park ret = aat2870->read(aat2870, ri->enable_addr, &val); 94f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park if (ret) 95f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park return ret; 96f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 97f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park return val & ri->enable_mask ? 1 : 0; 98f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park} 99f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 100f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic struct regulator_ops aat2870_ldo_ops = { 1014506c6d5ea5dddab562fd06398fd9b8d1681bbd0Axel Lin .list_voltage = regulator_list_voltage_table, 10208d6da291435f5de0f0fa283994a74f67d9ab23aAxel Lin .map_voltage = regulator_map_voltage_ascend, 103f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park .set_voltage_sel = aat2870_ldo_set_voltage_sel, 104f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park .get_voltage_sel = aat2870_ldo_get_voltage_sel, 105f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park .enable = aat2870_ldo_enable, 106f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park .disable = aat2870_ldo_disable, 107f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park .is_enabled = aat2870_ldo_is_enabled, 108f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park}; 109f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 1104506c6d5ea5dddab562fd06398fd9b8d1681bbd0Axel Linstatic const unsigned int aat2870_ldo_voltages[] = { 111f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 1200000, 1300000, 1500000, 1600000, 112f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 1800000, 2000000, 2200000, 2500000, 113f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 2600000, 2700000, 2800000, 2900000, 114f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 3000000, 3100000, 3200000, 3300000, 115f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park}; 116f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 117f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park#define AAT2870_LDO(ids) \ 118f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park { \ 119f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park .desc = { \ 120f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park .name = #ids, \ 121f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park .id = AAT2870_ID_##ids, \ 122f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park .n_voltages = ARRAY_SIZE(aat2870_ldo_voltages), \ 1234506c6d5ea5dddab562fd06398fd9b8d1681bbd0Axel Lin .volt_table = aat2870_ldo_voltages, \ 124f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park .ops = &aat2870_ldo_ops, \ 125f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park .type = REGULATOR_VOLTAGE, \ 126f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park .owner = THIS_MODULE, \ 127f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park }, \ 128f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park } 129f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 130f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic struct aat2870_regulator aat2870_regulators[] = { 131f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park AAT2870_LDO(LDOA), 132f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park AAT2870_LDO(LDOB), 133f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park AAT2870_LDO(LDOC), 134f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park AAT2870_LDO(LDOD), 135f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park}; 136f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 137f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic struct aat2870_regulator *aat2870_get_regulator(int id) 138f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park{ 139f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park struct aat2870_regulator *ri = NULL; 140f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park int i; 141f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 142f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park for (i = 0; i < ARRAY_SIZE(aat2870_regulators); i++) { 143f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park ri = &aat2870_regulators[i]; 144f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park if (ri->desc.id == id) 145f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park break; 146f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park } 147f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 148d4d6373c1109b11c8118340be97ae31b8f94d66aAxel Lin if (i == ARRAY_SIZE(aat2870_regulators)) 149f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park return NULL; 150f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 151f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park ri->enable_addr = AAT2870_LDO_EN; 152f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park ri->enable_shift = id - AAT2870_ID_LDOA; 153f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park ri->enable_mask = 0x1 << ri->enable_shift; 154f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 155f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park ri->voltage_addr = (id - AAT2870_ID_LDOA) / 2 ? 156f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park AAT2870_LDO_CD : AAT2870_LDO_AB; 157f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park ri->voltage_shift = (id - AAT2870_ID_LDOA) % 2 ? 0 : 4; 158f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park ri->voltage_mask = 0xF << ri->voltage_shift; 159f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 160f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park return ri; 161f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park} 162f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 163f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic int aat2870_regulator_probe(struct platform_device *pdev) 164f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park{ 165f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park struct aat2870_regulator *ri; 166e4c5288e410440abcc3e2e1887111b09a98304d5Mark Brown struct regulator_config config = { }; 167f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park struct regulator_dev *rdev; 168f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 169f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park ri = aat2870_get_regulator(pdev->id); 170f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park if (!ri) { 171f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park dev_err(&pdev->dev, "Invalid device ID, %d\n", pdev->id); 172f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park return -EINVAL; 173f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park } 174b21bcd1ada026cd90243311e89dd8d999fe0a227Axel Lin ri->aat2870 = dev_get_drvdata(pdev->dev.parent); 175f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 176c172708d38a401b2f3f841dfcd862b469fa0b670Mark Brown config.dev = &pdev->dev; 177c172708d38a401b2f3f841dfcd862b469fa0b670Mark Brown config.driver_data = ri; 178dff91d0b721bf8f036c1071a8f16a7effaa87514Jingoo Han config.init_data = dev_get_platdata(&pdev->dev); 179c172708d38a401b2f3f841dfcd862b469fa0b670Mark Brown 180b1a613d505c53ad4f4af4cf228841a1784a50011Axel Lin rdev = devm_regulator_register(&pdev->dev, &ri->desc, &config); 181f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park if (IS_ERR(rdev)) { 182f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park dev_err(&pdev->dev, "Failed to register regulator %s\n", 183f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park ri->desc.name); 184f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park return PTR_ERR(rdev); 185f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park } 186f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park platform_set_drvdata(pdev, rdev); 187f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 188f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park return 0; 189f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park} 190f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 191f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic struct platform_driver aat2870_regulator_driver = { 192f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park .driver = { 193f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park .name = "aat2870-regulator", 194f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park .owner = THIS_MODULE, 195f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park }, 196f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park .probe = aat2870_regulator_probe, 197f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park}; 198f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 199f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic int __init aat2870_regulator_init(void) 200f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park{ 201f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park return platform_driver_register(&aat2870_regulator_driver); 202f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park} 203f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parksubsys_initcall(aat2870_regulator_init); 204f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 205f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic void __exit aat2870_regulator_exit(void) 206f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park{ 207f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park platform_driver_unregister(&aat2870_regulator_driver); 208f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park} 209f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkmodule_exit(aat2870_regulator_exit); 210f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 211f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin ParkMODULE_DESCRIPTION("AnalogicTech AAT2870 Regulator"); 212f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin ParkMODULE_LICENSE("GPL"); 213f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin ParkMODULE_AUTHOR("Jin Park <jinyoungp@nvidia.com>"); 214ad9c5ffea8de1d989e205650bb46111b37498cf3Mark BrownMODULE_ALIAS("platform:aat2870-regulator"); 215