/* * drivers/power/axp/axp22x/axp22x-virtual.c * (C) Copyright 2010-2016 * Allwinner Technology Co., Ltd. * Pannan * * virtual regulator driver of axp22x * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * */ #include #include #include #include #include #include #include "../axp-virtual.h" struct axp_virtual_dev_mapping axp803_mapping[] = { {"reg-803-cs-rtc", "axp803_rtc"}, {"reg-803-cs-aldo1", "axp803_aldo1"}, {"reg-803-cs-aldo2", "axp803_aldo2"}, {"reg-803-cs-aldo3", "axp803_aldo3"}, {"reg-803-cs-dldo1", "axp803_dldo1"}, {"reg-803-cs-dldo2", "axp803_dldo2"}, {"reg-803-cs-dldo3", "axp803_dldo3"}, {"reg-803-cs-dldo4", "axp803_dldo4"}, {"reg-803-cs-eldo1", "axp803_eldo1"}, {"reg-803-cs-eldo2", "axp803_eldo2"}, {"reg-803-cs-eldo3", "axp803_eldo3"}, {"reg-803-cs-fldo1", "axp803_fldo1"}, {"reg-803-cs-fldo2", "axp803_fldo2"}, {"reg-803-cs-dcdc1", "axp803_dcdc1"}, {"reg-803-cs-dcdc2", "axp803_dcdc2"}, {"reg-803-cs-dcdc3", "axp803_dcdc3"}, {"reg-803-cs-dcdc4", "axp803_dcdc4"}, {"reg-803-cs-dcdc5", "axp803_dcdc5"}, {"reg-803-cs-dcdc6", "axp803_dcdc6"}, {"reg-803-cs-dcdc7", "axp803_dcdc7"}, {"reg-803-cs-ldoio0", "axp803_ldoio0"}, {"reg-803-cs-ldoio1", "axp803_ldoio1"}, {"reg-803-cs-dc1sw", "axp803_dc1sw"}, }; static struct platform_device axp803_vr_pdev[ARRAY_SIZE(axp803_mapping)]; static struct platform_driver axp803_vr_pdrv[ARRAY_SIZE(axp803_mapping)]; static int axp803_vrd_probe(struct platform_device *pdev) { char *reg_id = pdev->dev.platform_data; struct virtual_consumer_data *drvdata; int ret, i; const char *pmu_name; for (i = 0; i < AXP_ONLINE_SUM; i++) { pmu_name = get_pmu_cur_name(i); if (pmu_name == NULL) continue; if (strncmp("axp803", pmu_name, 6)) continue; else break; } if (i == AXP_ONLINE_SUM) return 0; drvdata = kzalloc(sizeof(struct virtual_consumer_data), GFP_KERNEL); if (drvdata == NULL) { ret = -ENOMEM; goto err; } mutex_init(&drvdata->lock); sprintf(drvdata->regu_name, reg_id); for (i = 0; i < ARRAY_SIZE(attributes_virtual); i++) { ret = device_create_file(&pdev->dev, attributes_virtual[i]); if (ret != 0) goto err; } platform_set_drvdata(pdev, drvdata); return 0; err: for (i = 0; i < ARRAY_SIZE(attributes_virtual); i++) device_remove_file(&pdev->dev, attributes_virtual[i]); kfree(drvdata); return ret; } static int axp803_vrd_remove(struct platform_device *pdev) { struct virtual_consumer_data *drvdata = platform_get_drvdata(pdev); int i; for (i = 0; i < ARRAY_SIZE(attributes_virtual); i++) device_remove_file(&pdev->dev, attributes_virtual[i]); kfree(drvdata); return 0; } static int __init axp803_virtual_regulator_pdrv_init(void) { int j, ret; ret = axp_add_virtual_regulator_devices(axp803_vr_pdev, ARRAY_SIZE(axp803_mapping), axp803_mapping); if (ret) { pr_err("%s: add virtual devices failed\n", __func__); return -EINVAL; } axp_init_virtual_regulator_drivers(axp803_vr_pdrv, ARRAY_SIZE(axp803_mapping), axp803_mapping, axp803_vrd_probe, axp803_vrd_remove); for (j = 0; j < ARRAY_SIZE(axp803_mapping); j++) { ret = platform_driver_register(&axp803_vr_pdrv[j]); if (ret) goto creat_drivers_failed; } return ret; creat_drivers_failed: while (j--) platform_driver_unregister( &axp803_vr_pdrv[j]); return ret; } module_init(axp803_virtual_regulator_pdrv_init); static void __exit axp803_virtual_regulator_pdrv_exit(void) { int j; for (j = ARRAY_SIZE(axp803_mapping) - 1; j >= 0; j--) platform_driver_unregister(&axp803_vr_pdrv[j]); for (j = 0; j < ARRAY_SIZE(axp803_mapping); j++) platform_device_unregister(&axp803_vr_pdev[j]); } module_exit(axp803_virtual_regulator_pdrv_exit); MODULE_DESCRIPTION("Virtual regulator driver of axp803"); MODULE_AUTHOR("pannan"); MODULE_LICENSE("GPL");