brintos

brintos / linux-shallow public Read only

0
0
Text · 11.9 KiB · 1e2d54d Raw
502 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (C) ST-Ericsson SA 20104 *5 * Authors: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson6 *          Bengt Jonsson <bengt.g.jonsson@stericsson.com> for ST-Ericsson7 *8 * Power domain regulators on DB85009 */10 11#include <linux/kernel.h>12#include <linux/init.h>13#include <linux/err.h>14#include <linux/spinlock.h>15#include <linux/platform_device.h>16#include <linux/mfd/dbx500-prcmu.h>17#include <linux/regulator/driver.h>18#include <linux/regulator/machine.h>19#include <linux/regulator/db8500-prcmu.h>20#include <linux/regulator/of_regulator.h>21#include <linux/of.h>22#include <linux/module.h>23#include "dbx500-prcmu.h"24 25static int db8500_regulator_enable(struct regulator_dev *rdev)26{27	struct dbx500_regulator_info *info = rdev_get_drvdata(rdev);28 29	if (info == NULL)30		return -EINVAL;31 32	dev_vdbg(rdev_get_dev(rdev), "regulator-%s-enable\n",33		info->desc.name);34 35	if (!info->is_enabled) {36		info->is_enabled = true;37		if (!info->exclude_from_power_state)38			power_state_active_enable();39	}40 41	return 0;42}43 44static int db8500_regulator_disable(struct regulator_dev *rdev)45{46	struct dbx500_regulator_info *info = rdev_get_drvdata(rdev);47	int ret = 0;48 49	if (info == NULL)50		return -EINVAL;51 52	dev_vdbg(rdev_get_dev(rdev), "regulator-%s-disable\n",53		info->desc.name);54 55	if (info->is_enabled) {56		info->is_enabled = false;57		if (!info->exclude_from_power_state)58			ret = power_state_active_disable();59	}60 61	return ret;62}63 64static int db8500_regulator_is_enabled(struct regulator_dev *rdev)65{66	struct dbx500_regulator_info *info = rdev_get_drvdata(rdev);67 68	if (info == NULL)69		return -EINVAL;70 71	dev_vdbg(rdev_get_dev(rdev), "regulator-%s-is_enabled (is_enabled):"72		" %i\n", info->desc.name, info->is_enabled);73 74	return info->is_enabled;75}76 77/* db8500 regulator operations */78static const struct regulator_ops db8500_regulator_ops = {79	.enable			= db8500_regulator_enable,80	.disable		= db8500_regulator_disable,81	.is_enabled		= db8500_regulator_is_enabled,82};83 84/*85 * EPOD control86 */87static bool epod_on[NUM_EPOD_ID];88static bool epod_ramret[NUM_EPOD_ID];89 90static int enable_epod(u16 epod_id, bool ramret)91{92	int ret;93 94	if (ramret) {95		if (!epod_on[epod_id]) {96			ret = prcmu_set_epod(epod_id, EPOD_STATE_RAMRET);97			if (ret < 0)98				return ret;99		}100		epod_ramret[epod_id] = true;101	} else {102		ret = prcmu_set_epod(epod_id, EPOD_STATE_ON);103		if (ret < 0)104			return ret;105		epod_on[epod_id] = true;106	}107 108	return 0;109}110 111static int disable_epod(u16 epod_id, bool ramret)112{113	int ret;114 115	if (ramret) {116		if (!epod_on[epod_id]) {117			ret = prcmu_set_epod(epod_id, EPOD_STATE_OFF);118			if (ret < 0)119				return ret;120		}121		epod_ramret[epod_id] = false;122	} else {123		if (epod_ramret[epod_id]) {124			ret = prcmu_set_epod(epod_id, EPOD_STATE_RAMRET);125			if (ret < 0)126				return ret;127		} else {128			ret = prcmu_set_epod(epod_id, EPOD_STATE_OFF);129			if (ret < 0)130				return ret;131		}132		epod_on[epod_id] = false;133	}134 135	return 0;136}137 138/*139 * Regulator switch140 */141static int db8500_regulator_switch_enable(struct regulator_dev *rdev)142{143	struct dbx500_regulator_info *info = rdev_get_drvdata(rdev);144	int ret;145 146	if (info == NULL)147		return -EINVAL;148 149	dev_vdbg(rdev_get_dev(rdev), "regulator-switch-%s-enable\n",150		info->desc.name);151 152	ret = enable_epod(info->epod_id, info->is_ramret);153	if (ret < 0) {154		dev_err(rdev_get_dev(rdev),155			"regulator-switch-%s-enable: prcmu call failed\n",156			info->desc.name);157		goto out;158	}159 160	info->is_enabled = true;161out:162	return ret;163}164 165static int db8500_regulator_switch_disable(struct regulator_dev *rdev)166{167	struct dbx500_regulator_info *info = rdev_get_drvdata(rdev);168	int ret;169 170	if (info == NULL)171		return -EINVAL;172 173	dev_vdbg(rdev_get_dev(rdev), "regulator-switch-%s-disable\n",174		info->desc.name);175 176	ret = disable_epod(info->epod_id, info->is_ramret);177	if (ret < 0) {178		dev_err(rdev_get_dev(rdev),179			"regulator_switch-%s-disable: prcmu call failed\n",180			info->desc.name);181		goto out;182	}183 184	info->is_enabled = false;185out:186	return ret;187}188 189static int db8500_regulator_switch_is_enabled(struct regulator_dev *rdev)190{191	struct dbx500_regulator_info *info = rdev_get_drvdata(rdev);192 193	if (info == NULL)194		return -EINVAL;195 196	dev_vdbg(rdev_get_dev(rdev),197		"regulator-switch-%s-is_enabled (is_enabled): %i\n",198		info->desc.name, info->is_enabled);199 200	return info->is_enabled;201}202 203static const struct regulator_ops db8500_regulator_switch_ops = {204	.enable			= db8500_regulator_switch_enable,205	.disable		= db8500_regulator_switch_disable,206	.is_enabled		= db8500_regulator_switch_is_enabled,207};208 209/*210 * Regulator information211 */212static struct dbx500_regulator_info213dbx500_regulator_info[DB8500_NUM_REGULATORS] = {214	[DB8500_REGULATOR_VAPE] = {215		.desc = {216			.name	= "db8500-vape",217			.of_match = of_match_ptr("db8500_vape"),218			.id	= DB8500_REGULATOR_VAPE,219			.ops	= &db8500_regulator_ops,220			.type	= REGULATOR_VOLTAGE,221			.owner	= THIS_MODULE,222		},223	},224	[DB8500_REGULATOR_VARM] = {225		.desc = {226			.name	= "db8500-varm",227			.of_match = of_match_ptr("db8500_varm"),228			.id	= DB8500_REGULATOR_VARM,229			.ops	= &db8500_regulator_ops,230			.type	= REGULATOR_VOLTAGE,231			.owner	= THIS_MODULE,232		},233	},234	[DB8500_REGULATOR_VMODEM] = {235		.desc = {236			.name	= "db8500-vmodem",237			.of_match = of_match_ptr("db8500_vmodem"),238			.id	= DB8500_REGULATOR_VMODEM,239			.ops	= &db8500_regulator_ops,240			.type	= REGULATOR_VOLTAGE,241			.owner	= THIS_MODULE,242		},243	},244	[DB8500_REGULATOR_VPLL] = {245		.desc = {246			.name	= "db8500-vpll",247			.of_match = of_match_ptr("db8500_vpll"),248			.id	= DB8500_REGULATOR_VPLL,249			.ops	= &db8500_regulator_ops,250			.type	= REGULATOR_VOLTAGE,251			.owner	= THIS_MODULE,252		},253	},254	[DB8500_REGULATOR_VSMPS1] = {255		.desc = {256			.name	= "db8500-vsmps1",257			.of_match = of_match_ptr("db8500_vsmps1"),258			.id	= DB8500_REGULATOR_VSMPS1,259			.ops	= &db8500_regulator_ops,260			.type	= REGULATOR_VOLTAGE,261			.owner	= THIS_MODULE,262		},263	},264	[DB8500_REGULATOR_VSMPS2] = {265		.desc = {266			.name	= "db8500-vsmps2",267			.of_match = of_match_ptr("db8500_vsmps2"),268			.id	= DB8500_REGULATOR_VSMPS2,269			.ops	= &db8500_regulator_ops,270			.type	= REGULATOR_VOLTAGE,271			.owner	= THIS_MODULE,272			.fixed_uV = 1800000,273			.n_voltages = 1,274		},275		.exclude_from_power_state = true,276	},277	[DB8500_REGULATOR_VSMPS3] = {278		.desc = {279			.name	= "db8500-vsmps3",280			.of_match = of_match_ptr("db8500_vsmps3"),281			.id	= DB8500_REGULATOR_VSMPS3,282			.ops	= &db8500_regulator_ops,283			.type	= REGULATOR_VOLTAGE,284			.owner	= THIS_MODULE,285		},286	},287	[DB8500_REGULATOR_VRF1] = {288		.desc = {289			.name	= "db8500-vrf1",290			.of_match = of_match_ptr("db8500_vrf1"),291			.id	= DB8500_REGULATOR_VRF1,292			.ops	= &db8500_regulator_ops,293			.type	= REGULATOR_VOLTAGE,294			.owner	= THIS_MODULE,295		},296	},297	[DB8500_REGULATOR_SWITCH_SVAMMDSP] = {298		.desc = {299			.name	= "db8500-sva-mmdsp",300			.of_match = of_match_ptr("db8500_sva_mmdsp"),301			.id	= DB8500_REGULATOR_SWITCH_SVAMMDSP,302			.ops	= &db8500_regulator_switch_ops,303			.type	= REGULATOR_VOLTAGE,304			.owner	= THIS_MODULE,305		},306		.epod_id = EPOD_ID_SVAMMDSP,307	},308	[DB8500_REGULATOR_SWITCH_SVAMMDSPRET] = {309		.desc = {310			.name	= "db8500-sva-mmdsp-ret",311			.of_match = of_match_ptr("db8500_sva_mmdsp_ret"),312			.id	= DB8500_REGULATOR_SWITCH_SVAMMDSPRET,313			.ops	= &db8500_regulator_switch_ops,314			.type	= REGULATOR_VOLTAGE,315			.owner	= THIS_MODULE,316		},317		.epod_id = EPOD_ID_SVAMMDSP,318		.is_ramret = true,319	},320	[DB8500_REGULATOR_SWITCH_SVAPIPE] = {321		.desc = {322			.name	= "db8500-sva-pipe",323			.of_match = of_match_ptr("db8500_sva_pipe"),324			.id	= DB8500_REGULATOR_SWITCH_SVAPIPE,325			.ops	= &db8500_regulator_switch_ops,326			.type	= REGULATOR_VOLTAGE,327			.owner	= THIS_MODULE,328		},329		.epod_id = EPOD_ID_SVAPIPE,330	},331	[DB8500_REGULATOR_SWITCH_SIAMMDSP] = {332		.desc = {333			.name	= "db8500-sia-mmdsp",334			.of_match = of_match_ptr("db8500_sia_mmdsp"),335			.id	= DB8500_REGULATOR_SWITCH_SIAMMDSP,336			.ops	= &db8500_regulator_switch_ops,337			.type	= REGULATOR_VOLTAGE,338			.owner	= THIS_MODULE,339		},340		.epod_id = EPOD_ID_SIAMMDSP,341	},342	[DB8500_REGULATOR_SWITCH_SIAMMDSPRET] = {343		.desc = {344			.name	= "db8500-sia-mmdsp-ret",345			.of_match = of_match_ptr("db8500_sia_mmdsp_ret"),346			.id	= DB8500_REGULATOR_SWITCH_SIAMMDSPRET,347			.ops	= &db8500_regulator_switch_ops,348			.type	= REGULATOR_VOLTAGE,349			.owner	= THIS_MODULE,350		},351		.epod_id = EPOD_ID_SIAMMDSP,352		.is_ramret = true,353	},354	[DB8500_REGULATOR_SWITCH_SIAPIPE] = {355		.desc = {356			.name	= "db8500-sia-pipe",357			.of_match = of_match_ptr("db8500_sia_pipe"),358			.id	= DB8500_REGULATOR_SWITCH_SIAPIPE,359			.ops	= &db8500_regulator_switch_ops,360			.type	= REGULATOR_VOLTAGE,361			.owner	= THIS_MODULE,362		},363		.epod_id = EPOD_ID_SIAPIPE,364	},365	[DB8500_REGULATOR_SWITCH_SGA] = {366		.desc = {367			.name	= "db8500-sga",368			.of_match = of_match_ptr("db8500_sga"),369			.id	= DB8500_REGULATOR_SWITCH_SGA,370			.ops	= &db8500_regulator_switch_ops,371			.type	= REGULATOR_VOLTAGE,372			.owner	= THIS_MODULE,373		},374		.epod_id = EPOD_ID_SGA,375	},376	[DB8500_REGULATOR_SWITCH_B2R2_MCDE] = {377		.desc = {378			.name	= "db8500-b2r2-mcde",379			.of_match = of_match_ptr("db8500_b2r2_mcde"),380			.id	= DB8500_REGULATOR_SWITCH_B2R2_MCDE,381			.ops	= &db8500_regulator_switch_ops,382			.type	= REGULATOR_VOLTAGE,383			.owner	= THIS_MODULE,384		},385		.epod_id = EPOD_ID_B2R2_MCDE,386	},387	[DB8500_REGULATOR_SWITCH_ESRAM12] = {388		.desc = {389			.name	= "db8500-esram12",390			.of_match = of_match_ptr("db8500_esram12"),391			.id	= DB8500_REGULATOR_SWITCH_ESRAM12,392			.ops	= &db8500_regulator_switch_ops,393			.type	= REGULATOR_VOLTAGE,394			.owner	= THIS_MODULE,395		},396		.epod_id	= EPOD_ID_ESRAM12,397		.is_enabled	= true,398	},399	[DB8500_REGULATOR_SWITCH_ESRAM12RET] = {400		.desc = {401			.name	= "db8500-esram12-ret",402			.of_match = of_match_ptr("db8500_esram12_ret"),403			.id	= DB8500_REGULATOR_SWITCH_ESRAM12RET,404			.ops	= &db8500_regulator_switch_ops,405			.type	= REGULATOR_VOLTAGE,406			.owner	= THIS_MODULE,407		},408		.epod_id = EPOD_ID_ESRAM12,409		.is_ramret = true,410	},411	[DB8500_REGULATOR_SWITCH_ESRAM34] = {412		.desc = {413			.name	= "db8500-esram34",414			.of_match = of_match_ptr("db8500_esram34"),415			.id	= DB8500_REGULATOR_SWITCH_ESRAM34,416			.ops	= &db8500_regulator_switch_ops,417			.type	= REGULATOR_VOLTAGE,418			.owner	= THIS_MODULE,419		},420		.epod_id	= EPOD_ID_ESRAM34,421		.is_enabled	= true,422	},423	[DB8500_REGULATOR_SWITCH_ESRAM34RET] = {424		.desc = {425			.name	= "db8500-esram34-ret",426			.of_match = of_match_ptr("db8500_esram34_ret"),427			.id	= DB8500_REGULATOR_SWITCH_ESRAM34RET,428			.ops	= &db8500_regulator_switch_ops,429			.type	= REGULATOR_VOLTAGE,430			.owner	= THIS_MODULE,431		},432		.epod_id = EPOD_ID_ESRAM34,433		.is_ramret = true,434	},435};436 437static int db8500_regulator_probe(struct platform_device *pdev)438{439	struct regulator_init_data *db8500_init_data;440	struct dbx500_regulator_info *info;441	struct regulator_config config = { };442	struct regulator_dev *rdev;443	int err, i;444 445	db8500_init_data = dev_get_platdata(&pdev->dev);446 447	for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) {448		/* assign per-regulator data */449		info = &dbx500_regulator_info[i];450 451		config.driver_data = info;452		config.dev = &pdev->dev;453		if (db8500_init_data)454			config.init_data = &db8500_init_data[i];455 456		rdev = devm_regulator_register(&pdev->dev, &info->desc,457					       &config);458		if (IS_ERR(rdev)) {459			err = PTR_ERR(rdev);460			dev_err(&pdev->dev, "failed to register %s: err %i\n",461				info->desc.name, err);462			return err;463		}464		dev_dbg(&pdev->dev, "regulator-%s-probed\n", info->desc.name);465	}466 467	ux500_regulator_debug_init(pdev, dbx500_regulator_info,468				   ARRAY_SIZE(dbx500_regulator_info));469	return 0;470}471 472static void db8500_regulator_remove(struct platform_device *pdev)473{474	ux500_regulator_debug_exit();475}476 477static struct platform_driver db8500_regulator_driver = {478	.driver = {479		.name = "db8500-prcmu-regulators",480		.probe_type = PROBE_PREFER_ASYNCHRONOUS,481	},482	.probe = db8500_regulator_probe,483	.remove_new = db8500_regulator_remove,484};485 486static int __init db8500_regulator_init(void)487{488	return platform_driver_register(&db8500_regulator_driver);489}490 491static void __exit db8500_regulator_exit(void)492{493	platform_driver_unregister(&db8500_regulator_driver);494}495 496arch_initcall(db8500_regulator_init);497module_exit(db8500_regulator_exit);498 499MODULE_AUTHOR("STMicroelectronics/ST-Ericsson");500MODULE_DESCRIPTION("DB8500 regulator driver");501MODULE_LICENSE("GPL v2");502