Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) // Copyright (c) 2019 five technologies GmbH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) // Author: Markus Reichl <m.reichl@fivetechno.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/regulator/driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #define VOL_MIN_IDX			0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #define VOL_MAX_IDX			0x7ff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) /* Register definitions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #define MP8859_VOUT_L_REG		0    //3 lo Bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #define MP8859_VOUT_H_REG		1    //8 hi Bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #define MP8859_VOUT_GO_REG		2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #define MP8859_IOUT_LIM_REG		3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #define MP8859_CTL1_REG			4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define MP8859_CTL2_REG			5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define MP8859_RESERVED1_REG		6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define MP8859_RESERVED2_REG		7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define MP8859_RESERVED3_REG		8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define MP8859_STATUS_REG		9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define MP8859_INTERRUPT_REG		0x0A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define MP8859_MASK_REG			0x0B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define MP8859_ID1_REG			0x0C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define MP8859_MFR_ID_REG		0x27
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define MP8859_DEV_ID_REG		0x28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define MP8859_IC_REV_REG		0x29
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define MP8859_MAX_REG			0x29
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define MP8859_GO_BIT			0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) static int mp8859_set_voltage_sel(struct regulator_dev *rdev, unsigned int sel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	ret = regmap_write(rdev->regmap, MP8859_VOUT_L_REG, sel & 0x7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	ret = regmap_write(rdev->regmap, MP8859_VOUT_H_REG, sel >> 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	ret = regmap_update_bits(rdev->regmap, MP8859_VOUT_GO_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 					MP8859_GO_BIT, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) static int mp8859_get_voltage_sel(struct regulator_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	unsigned int val_tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	ret = regmap_read(rdev->regmap, MP8859_VOUT_H_REG, &val_tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	val = val_tmp << 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	ret = regmap_read(rdev->regmap, MP8859_VOUT_L_REG, &val_tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	val |= val_tmp & 0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) static const struct linear_range mp8859_dcdc_ranges[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	REGULATOR_LINEAR_RANGE(0, VOL_MIN_IDX, VOL_MAX_IDX, 10000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) static const struct regmap_config mp8859_regmap = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	.reg_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	.val_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	.max_register = MP8859_MAX_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	.cache_type = REGCACHE_RBTREE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) static const struct regulator_ops mp8859_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	.set_voltage_sel = mp8859_set_voltage_sel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	.get_voltage_sel = mp8859_get_voltage_sel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	.list_voltage = regulator_list_voltage_linear_range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) static const struct regulator_desc mp8859_regulators[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		.id = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		.type = REGULATOR_VOLTAGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		.name = "mp8859_dcdc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		.supply_name = "vin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		.of_match = of_match_ptr("mp8859_dcdc"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		.n_voltages = VOL_MAX_IDX + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		.linear_ranges = mp8859_dcdc_ranges,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		.n_linear_ranges = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		.ops = &mp8859_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		.owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static int mp8859_i2c_probe(struct i2c_client *i2c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	struct regulator_config config = {.dev = &i2c->dev};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	struct regmap *regmap = devm_regmap_init_i2c(i2c, &mp8859_regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	struct regulator_dev *rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	if (IS_ERR(regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		ret = PTR_ERR(regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		dev_err(&i2c->dev, "regmap init failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	rdev = devm_regulator_register(&i2c->dev, &mp8859_regulators[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 					&config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	if (IS_ERR(rdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		ret = PTR_ERR(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		dev_err(&i2c->dev, "failed to register %s: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 			mp8859_regulators[0].name, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static const struct of_device_id mp8859_dt_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	{.compatible =  "mps,mp8859"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	{},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) MODULE_DEVICE_TABLE(of, mp8859_dt_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static const struct i2c_device_id mp8859_i2c_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	{ "mp8859", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	{  },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) MODULE_DEVICE_TABLE(i2c, mp8859_i2c_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static struct i2c_driver mp8859_regulator_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		.name = "mp8859",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		.of_match_table = of_match_ptr(mp8859_dt_id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	.probe_new = mp8859_i2c_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	.id_table = mp8859_i2c_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) module_i2c_driver(mp8859_regulator_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) MODULE_DESCRIPTION("Monolithic Power Systems MP8859 voltage regulator driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) MODULE_AUTHOR("Markus Reichl <m.reichl@fivetechno.de>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) MODULE_LICENSE("GPL v2");