/* * drivers/power/axp/axp80x/axp80x-virtual.c * (C) Copyright 2010-2016 * Allwinner Technology Co., Ltd. * Pannan * * virtual regulator driver of axp80x * * 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 axp80x_mapping[] = { {"reg-80-cs-sw", "axp80x_sw"}, {"reg-80-cs-aldo1", "axp80x_aldo1"}, {"reg-80-cs-aldo2", "axp80x_aldo2"}, {"reg-80-cs-aldo3", "axp80x_aldo3"}, {"reg-80-cs-bldo1", "axp80x_bldo1"}, {"reg-80-cs-bldo2", "axp80x_bldo2"}, {"reg-80-cs-bldo3", "axp80x_bldo3"}, {"reg-80-cs-bldo4", "axp80x_bldo4"}, {"reg-80-cs-cldo1", "axp80x_cldo1"}, {"reg-80-cs-cldo2", "axp80x_cldo2"}, {"reg-80-cs-cldo3", "axp80x_cldo3"}, {"reg-80-cs-dcdca", "axp80x_dcdca"}, {"reg-80-cs-dcdcb", "axp80x_dcdcb"}, {"reg-80-cs-dcdcc", "axp80x_dcdcc"}, {"reg-80-cs-dcdcd", "axp80x_dcdcd"}, {"reg-80-cs-dcdce", "axp80x_dcdce"}, }; static struct platform_device axp80x_vr_pdev[ARRAY_SIZE(axp80x_mapping)]; static struct platform_driver axp80x_vr_pdrv[ARRAY_SIZE(axp80x_mapping)]; static int axp80x_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("axp80", pmu_name, 5)) 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 axp80x_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 axp80x_virtual_regulator_pdrv_init(void) { int j, ret; ret = axp_add_virtual_regulator_devices(axp80x_vr_pdev, ARRAY_SIZE(axp80x_mapping), axp80x_mapping); if (ret) { pr_err("%s: add virtual devices failed\n", __func__); return -EINVAL; } axp_init_virtual_regulator_drivers(axp80x_vr_pdrv, ARRAY_SIZE(axp80x_mapping), axp80x_mapping, axp80x_vrd_probe, axp80x_vrd_remove); for (j = 0; j < ARRAY_SIZE(axp80x_mapping); j++) { ret = platform_driver_register(&axp80x_vr_pdrv[j]); if (ret) goto creat_drivers_failed; } return ret; creat_drivers_failed: while (j--) platform_driver_unregister( &axp80x_vr_pdrv[j]); return ret; } module_init(axp80x_virtual_regulator_pdrv_init); static void __exit axp80x_virtual_regulator_pdrv_exit(void) { int j; for (j = ARRAY_SIZE(axp80x_mapping) - 1; j >= 0; j--) platform_driver_unregister(&axp80x_vr_pdrv[j]); for (j = 0; j < ARRAY_SIZE(axp80x_mapping); j++) platform_device_unregister(&axp80x_vr_pdev[j]); } module_exit(axp80x_virtual_regulator_pdrv_exit); MODULE_DESCRIPTION("Virtual regulator driver of axp80x"); MODULE_AUTHOR("pannan"); MODULE_LICENSE("GPL");