aat2870-regulator.c revision e4c5288e410440abcc3e2e1887111b09a98304d5
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, 102f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park .set_voltage_sel = aat2870_ldo_set_voltage_sel, 103f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park .get_voltage_sel = aat2870_ldo_get_voltage_sel, 104f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park .enable = aat2870_ldo_enable, 105f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park .disable = aat2870_ldo_disable, 106f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park .is_enabled = aat2870_ldo_is_enabled, 107f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park}; 108f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 1094506c6d5ea5dddab562fd06398fd9b8d1681bbd0Axel Linstatic const unsigned int aat2870_ldo_voltages[] = { 110f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 1200000, 1300000, 1500000, 1600000, 111f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 1800000, 2000000, 2200000, 2500000, 112f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 2600000, 2700000, 2800000, 2900000, 113f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 3000000, 3100000, 3200000, 3300000, 114f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park}; 115f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 116f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park#define AAT2870_LDO(ids) \ 117f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park { \ 118f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park .desc = { \ 119f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park .name = #ids, \ 120f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park .id = AAT2870_ID_##ids, \ 121f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park .n_voltages = ARRAY_SIZE(aat2870_ldo_voltages), \ 1224506c6d5ea5dddab562fd06398fd9b8d1681bbd0Axel Lin .volt_table = aat2870_ldo_voltages, \ 123f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park .ops = &aat2870_ldo_ops, \ 124f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park .type = REGULATOR_VOLTAGE, \ 125f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park .owner = THIS_MODULE, \ 126f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park }, \ 127f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park } 128f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 129f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic struct aat2870_regulator aat2870_regulators[] = { 130f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park AAT2870_LDO(LDOA), 131f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park AAT2870_LDO(LDOB), 132f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park AAT2870_LDO(LDOC), 133f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park AAT2870_LDO(LDOD), 134f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park}; 135f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 136f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic struct aat2870_regulator *aat2870_get_regulator(int id) 137f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park{ 138f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park struct aat2870_regulator *ri = NULL; 139f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park int i; 140f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 141f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park for (i = 0; i < ARRAY_SIZE(aat2870_regulators); i++) { 142f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park ri = &aat2870_regulators[i]; 143f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park if (ri->desc.id == id) 144f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park break; 145f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park } 146f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 147d4d6373c1109b11c8118340be97ae31b8f94d66aAxel Lin if (i == ARRAY_SIZE(aat2870_regulators)) 148f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park return NULL; 149f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 150f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park ri->enable_addr = AAT2870_LDO_EN; 151f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park ri->enable_shift = id - AAT2870_ID_LDOA; 152f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park ri->enable_mask = 0x1 << ri->enable_shift; 153f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 154f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park ri->voltage_addr = (id - AAT2870_ID_LDOA) / 2 ? 155f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park AAT2870_LDO_CD : AAT2870_LDO_AB; 156f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park ri->voltage_shift = (id - AAT2870_ID_LDOA) % 2 ? 0 : 4; 157f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park ri->voltage_mask = 0xF << ri->voltage_shift; 158f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 159f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park return ri; 160f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park} 161f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 162f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic int aat2870_regulator_probe(struct platform_device *pdev) 163f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park{ 164f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park struct aat2870_regulator *ri; 165e4c5288e410440abcc3e2e1887111b09a98304d5Mark Brown struct regulator_config config = { }; 166f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park struct regulator_dev *rdev; 167f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 168f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park ri = aat2870_get_regulator(pdev->id); 169f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park if (!ri) { 170f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park dev_err(&pdev->dev, "Invalid device ID, %d\n", pdev->id); 171f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park return -EINVAL; 172f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park } 173b21bcd1ada026cd90243311e89dd8d999fe0a227Axel Lin ri->aat2870 = dev_get_drvdata(pdev->dev.parent); 174f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 175c172708d38a401b2f3f841dfcd862b469fa0b670Mark Brown config.dev = &pdev->dev; 176c172708d38a401b2f3f841dfcd862b469fa0b670Mark Brown config.driver_data = ri; 177c172708d38a401b2f3f841dfcd862b469fa0b670Mark Brown config.init_data = pdev->dev.platform_data; 178c172708d38a401b2f3f841dfcd862b469fa0b670Mark Brown 179c172708d38a401b2f3f841dfcd862b469fa0b670Mark Brown rdev = regulator_register(&ri->desc, &config); 180f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park if (IS_ERR(rdev)) { 181f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park dev_err(&pdev->dev, "Failed to register regulator %s\n", 182f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park ri->desc.name); 183f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park return PTR_ERR(rdev); 184f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park } 185f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park platform_set_drvdata(pdev, rdev); 186f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 187f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park return 0; 188f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park} 189f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 190f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic int __devexit aat2870_regulator_remove(struct platform_device *pdev) 191f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park{ 192f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park struct regulator_dev *rdev = platform_get_drvdata(pdev); 193f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 194f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park regulator_unregister(rdev); 195f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park return 0; 196f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park} 197f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 198f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic struct platform_driver aat2870_regulator_driver = { 199f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park .driver = { 200f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park .name = "aat2870-regulator", 201f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park .owner = THIS_MODULE, 202f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park }, 203f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park .probe = aat2870_regulator_probe, 204f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park .remove = __devexit_p(aat2870_regulator_remove), 205f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park}; 206f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 207f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic int __init aat2870_regulator_init(void) 208f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park{ 209f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park return platform_driver_register(&aat2870_regulator_driver); 210f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park} 211f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parksubsys_initcall(aat2870_regulator_init); 212f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 213f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic void __exit aat2870_regulator_exit(void) 214f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park{ 215f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park platform_driver_unregister(&aat2870_regulator_driver); 216f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park} 217f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkmodule_exit(aat2870_regulator_exit); 218f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park 219f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin ParkMODULE_DESCRIPTION("AnalogicTech AAT2870 Regulator"); 220f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin ParkMODULE_LICENSE("GPL"); 221f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin ParkMODULE_AUTHOR("Jin Park <jinyoungp@nvidia.com>"); 222ad9c5ffea8de1d989e205650bb46111b37498cf3Mark BrownMODULE_ALIAS("platform:aat2870-regulator"); 223